< C# Raw Socket Ping Program Example | Main | C++ & C# Raw Socket IGMP Program Examples >

 


 

Chapter 8 Part 21:

Client (and Server) Sockets Communication

 

 

What we have in this chapter 8 Part 21?

  1. C# Raw Socket Ping Program Example (Continue)

 

C# Raw Socket Ping Program Example (Continue)

 

Next, add another class and its code, you might name it WinsockPingClass. The Main() is in this class.

 

 

 

    /// <summary>

    /// This class implements IPv4 and IPv6 ping.

    /// </summary>

    public class WinsockPingClass

    {

        /// <summary>

        /// Displays simple usage information for the ping sample.

        /// </summary>

        static void usage()

        {

            Console.WriteLine("Usage: Executable_file_name [-a 4 | 6] [-i ttl] [-l bytes] [-n count] destination");

            Console.WriteLine(" Options:");

            Console.WriteLine("     -a 4 | 6        Forces IPv4 or IPv6");

            Console.WriteLine("     -i ttl          Indicates the time-to-live (TTL) to set on ping requests");

            Console.WriteLine("     -l byte-count   Number of bytes to put in ping payload");

            Console.WriteLine("     -n count        Number of echo requests to send");

            Console.WriteLine("     destination     Destination address or host name to ping");

            Console.WriteLine("...Else default values will be used...");

            Console.WriteLine();

        }

 

Add the Main() code.

 

        /// <summary>

        /// The main entry point for the application.

        /// </summary>

        static void Main(string[ ] args)

        {

            System.Diagnostics.Process proc;

            RawSocketPing pingSocket = null;

            AddressFamily addressFamily = AddressFamily.Unspecified;

            string remoteHost = "localhost";

            IPAddress remoteAddress = null;

            int dataSize = 512, ttlValue = 128, sendCount = 4;

 

            usage();

            Console.WriteLine();

 

            // Parse the command line

            for (int i = 0; i < args.Length; i++)

            {

                try

                {

                    if ((args[i][0] == '-') || (args[i][0] == '/'))

                    {

                        switch (Char.ToLower(args[i][1]))

                        {

                            case 'a':

                                // Force to ping over IPv4 or IPv6

                                int af = System.Convert.ToInt32(args[++i].ToString());

 

                                if (af == 4)

                                {

                                    addressFamily = AddressFamily.InterNetwork;

                                }

                                else if (af == 6)

                                {

                                    addressFamily = AddressFamily.InterNetworkV6;

                                }

                                else

                                {

                                    usage();

                                    return;

                                }

                                break;

                            case 'i':

                                // What TTL value to set on ping echo request?

                                ttlValue = System.Convert.ToInt32(args[++i].ToString());

                                break;

                            case 'l':

                                // How many bytes in the ping echo request payload?

                                dataSize = System.Convert.ToInt32(args[++i].ToString());

                                break;

                            case 'n':

                                // How many times to send an echo request

                                sendCount = System.Convert.ToInt32(args[++i].ToString());

                                break;

                            default:

                                usage();

                                return;

                        }

                    }

                    else

                    {

                        // If argument doesn't start with a '-' or '/' assume its the

                        //    hostname we're to ping

                        remoteHost = args[i];

                    }

                }

                catch

                {

                    usage();

                    return;

                }

            }

 

            // Try to resolve the address or name passed

            try

            {

                IPHostEntry hostEntry = Dns.GetHostEntry(remoteHost);

 

                if (hostEntry.AddressList.Length == 0)

                {

                    Console.WriteLine("Ping request could not fine host {0}. Please check the name and try again", remoteHost);

                    return;

                }

 

                if (addressFamily == AddressFamily.Unspecified)

                {

                    // No preference was specified so take first address

                    remoteAddress = hostEntry.AddressList[0];

                }

                else

                {

                    // Try to find a resolved address that matches the user selection

                    foreach (IPAddress addr in hostEntry.AddressList)

                    {

                        remoteAddress = addr;

 

                        if (remoteAddress.AddressFamily == addressFamily)

                            break;

                        remoteAddress = null;

                    }

 

                    if (remoteAddress == null)

                    {

                        Console.WriteLine("Ping request could not fine host {0}. Please check the name and try again", remoteHost);

                        return;

                    }

                }

            }

            catch (SocketException err)

            {

                Console.WriteLine("Bad name {0}: {1}", remoteHost, err.Message);

                return;

            }

 

            // Get our process ID which we'll use in the ICMP ID field

            proc = System.Diagnostics.Process.GetCurrentProcess();

 

            try

            {

                // Create a RawSocketPing class that wraps all the ping functionality

                pingSocket = new RawSocketPing(

                    remoteAddress.AddressFamily,

                    ttlValue,

                    dataSize,

                    sendCount,

                    (ushort)proc.Id

                    );

 

                Console.WriteLine("Starting from Main()...");

                Console.WriteLine();

                // Set the destination address we want to ping

                Console.WriteLine("Setting the destination address...");

                pingSocket.PingAddress = remoteAddress;

                Console.WriteLine();

                // Initialize the raw socket

                Console.WriteLine("Initializing the raw socket...");

                pingSocket.InitializeSocket();

                Console.WriteLine();

                // Create the ICMP packets to send

                Console.WriteLine("Creating the ICMP packets to send...");

                pingSocket.BuildPingPacket();

                Console.WriteLine();

                // Actually send the ping request and wait for response

                Console.WriteLine("Sending the ping request and wait for response...");

                pingSocket.DoPing();

            }

            catch (SocketException err)

            {

                Console.WriteLine("Socket error occurred: {0}", err.Message);

            }

            finally

            {

                if (pingSocket != null)

                    pingSocket.Close();

            }

            return;

        }

 

We need to add references to the Protocol.cs so that all the definition defined in the ProtocolHeaderDefinition can be resolved. Select the project folder > Right click mouse > Select Add context menu > Select Existing Item context menu.

 

C# Raw Socket Ping Program Example - adding an existing item into the project  

 

Browse and find the Protocol.cs file created previously. Select the file and click Add.

 

C# Raw Socket Ping Program Example - browsing and finding the protocol.cs file

 

You can see the Protocol.cs file is included under the project folder as shown in the following Figure.

 

C# Raw Socket Ping Program Example - the included source file into the project can be seen in the Solution Explorer

 

Next, build the project and make sure there is no error.

 

C# Raw Socket Ping Program Example - building the project

 

Then, run the project. Any error will be thrown by the exception handlers.

 

C# Raw Socket Ping Program Example - running the project

 

The following is the sample output.

 

C# Raw Socket Ping Program Example - a sample output with default argument values

 

The following is a sample output when run at the command prompt.

 

C# Raw Socket Ping Program Example - a sample output with supplied arguments

 

 

 


 

< C# Raw Socket Ping Program Example | Main | C++ & C# Raw Socket IGMP Program Examples >