Click here to Skip to main content
15,879,474 members
Articles / Programming Languages / C#

IP Server

Rate me:
Please Sign up or sign in to vote.
4.14/5 (5 votes)
3 Mar 2009CPOL1 min read 27.7K   1.3K   26  
An IP server that pings a range of IP addresses.
//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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Lebanon Lebanon
Works in a multinational pharmaceutical company as an IT specialist. A freelance software developer and web designer.

Comments and Discussions