|
//Server Code
//Distributed Systems (Client/Server Project)
//By Mohammad Mahjoub and Zahi Ismail
//Presented to Dr. Ramzi Haraty
//23/4/2007
//About Project:
//The client issues a request to get status of range of IP addresses
//The server fetches the request and checks the status by issuing successive ping commands
//to each IP address in the range, it then returns the results to the client to be displayed
//to the user.The server can serve many clients concurrently.
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
public class Server {
public static String myAddress;//address range received from the client
public static String myMessage;//message containing the results to be returned to the client
public static Ping ping = new Ping();//Create a new Ping instance using Ping class
public static void Main() {
try {
IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); //Using localhost address
TcpListener theList = new TcpListener(ipAddress, 2000); //Initializes the listener to localhost address and port 2000
Console.WriteLine("\nServer started");
Console.WriteLine("The server is running at 127.0.0.1:2000...");
Console.WriteLine("Waiting for an incoming connection.....");
while (true)
{
theList.Start(); //Start listening
Socket s = theList.AcceptSocket();//accept the client connection
Console.WriteLine("\nConnection accepted from host " + s.RemoteEndPoint);
Console.WriteLine("\nWaiting for IP range");
byte[] b = new byte[100];//buffer to store incoming characters stream
int k = s.Receive(b);//k is the number of characters received
for (int i = 0; i < k; i++)
{
myAddress = myAddress + (Convert.ToChar(b[i]).ToString());//Convert received characters stream into string
} //store the incoming range in myAddress variable
Console.WriteLine("\nIP range:");
string[] addressRange = myAddress.Split(new Char[] { '|' });//Split based on the character |
Console.WriteLine("From:" + addressRange[0] + " To:" + addressRange[1]);
string[] fromAddress = addressRange[0].Split(new Char[] { '.' });//Split the lower bound IP address into four octets
string[] toAddress = addressRange[1].Split(new Char[] { '.' });//Split the upper bound IP address into four octets
String fromFirst = fromAddress[0];//Lower bound first octet
String fromSecond = fromAddress[1];//Lower bound second octet
String fromThird = fromAddress[2];//Lower bound third octet
String fromFourth = fromAddress[3];//Lower bound fourth octet
String toFourth = toAddress[3];//Upper bound last octet
//The below routine does the ping for each IP address in the range
for (int x = int.Parse(fromFourth); x <= int.Parse(toFourth); x++)
{
ping.Open();
TimeSpan span = ping.Send(fromFirst.ToString() + "." + fromSecond.ToString() + "." + fromThird.ToString() + "." + x.ToString(), new TimeSpan(0, 0, 5));
ping.Close();
//Appending the result of each ping to myMessage string to be send to the host
if (span == TimeSpan.MaxValue)
myMessage = myMessage + (fromFirst.ToString() + "." + fromSecond.ToString() + "." + fromThird.ToString() + "." + x.ToString() + " Offline\n");
else
{
myMessage = myMessage + (fromFirst.ToString() + "." + fromSecond.ToString() + "." + fromThird.ToString() + "." + x.ToString() + " Online\n");
}
}//end of for loop
ASCIIEncoding asen = new ASCIIEncoding();//Sending ping results to the host using ASCII encoding
s.Send(asen.GetBytes(myMessage));
Console.WriteLine("\nIP range processed by the server");
Console.WriteLine("\nIP status results sent to client");
myAddress = "";//Resetting myAddress string
myMessage = "";//Resetting myMessage string
s.Close();
}//End of while loop
}//End of try block
catch (Exception ex) {
Console.WriteLine("Host disconnected");
}
}
}
#region Ping
public class Ping
{
/*_______________________________________________________________*/
// methods: Construction
#region
// Constructor
public Ping()
{
// create command field
pingCommand = new byte[8];
pingCommand[0] = 8; // Type
pingCommand[1] = 0; // Subtype
pingCommand[2] = 0; // Checksum
pingCommand[3] = 0;
pingCommand[4] = 1; // Identifier
pingCommand[5] = 0;
pingCommand[6] = 0; // Sequence number
pingCommand[7] = 0;
// create result field
pingResult = new byte[pingCommand.Length + 1000]; // returned IP Header + optional data
}
#endregion
/*_______________________________________________________________*/
// methods: Open, Close, Send
#region
// Open
public void Open()
{
// create socket and connect
socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
isOpen = true;
// create read complete event
readComplete = new ManualResetEvent(false);
}
// Close
public void Close()
{
// clear open flag
isOpen = false;
// close socket
socket.Close();
// close event
readComplete.Close();
}
// Send
public TimeSpan Send(string address, TimeSpan timeout) // This method returns TimsSpan
{
// empty result buffer
while (socket.Available > 0)
socket.Receive(pingResult, Math.Min(socket.Available, pingResult.Length), SocketFlags.None);
// reset event
readComplete.Reset();
// save start time
DateTime timeSend = DateTime.Now;
// complete ping command
pingCommand[6] = lastSequenceNr++;
SetChecksum(pingCommand);
// send ping command, start receive command
try
{
int iSend = socket.SendTo(pingCommand, new IPEndPoint(IPAddress.Parse(address), 0));
socket.BeginReceive(pingResult, 0, pingResult.Length, SocketFlags.None, new AsyncCallback(CallBack), null);
// wait until data received or timeout
if (readComplete.WaitOne(timeout, false))
{
// check result
if ((pingResult[20] == 0) &&
(pingCommand[4] == pingResult[24]) && (pingCommand[5] == pingResult[25]) &&
(pingCommand[6] == pingResult[26]) && (pingCommand[7] == pingResult[27]))
// return time delay
return DateTime.Now.Subtract(timeSend);
}
// return timeout
return TimeSpan.MaxValue;
}
catch (Exception ex)
{
return TimeSpan.MaxValue;
}
}
#endregion
/*_______________________________________________________________*/
// methods: CallBack
#region
protected void CallBack(IAsyncResult result)
{
if (isOpen)
{
try { socket.EndReceive(result); }
catch (Exception) { }
readComplete.Set();
}
}
#endregion
/*_______________________________________________________________*/
// methods: SetChecksum
#region
protected void SetChecksum(byte[] tel)
{
// reset old checksum
tel[2] = 0;
tel[3] = 0;
// calculate new checksum
uint cs = 0;
for (int i = 0; i < pingCommand.Length; i = i + 2)
cs += BitConverter.ToUInt16(pingCommand, i);
cs = ~((cs & 0xffffu) + (cs >> 16));
// set new checksum
tel[2] = (byte)cs;
tel[3] = (byte)(cs >> 8);
}
#endregion
/*...............................................................*/
// fields
// socket and event
protected Socket socket;
protected bool isOpen;
protected ManualResetEvent readComplete;
protected byte lastSequenceNr = 0;
// ping command and result fields
protected byte[] pingCommand;
protected byte[] pingResult;
}
#endregion
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Works in a multinational pharmaceutical company as an IT specialist. A freelance software developer and web designer.