Compile your own ping tool
Ping is a tool used to detect the network connection speed. The following article describes how to use system. net. sockets in C # To create a ping tool. -------------------------------------------------------------------------------- Ping is a tool used to detect the network connection speed. It establishes a socket connection between the local host and the remote host name and sends an ICMP packet to it, then the remote host responds and sends back a data packet. By calculating the time interval between the sent and received data packets, we can determine the connection speed.
Use Ping <Hostname> Host Name [/R] The optional attribute determines whether to continuously ping the remote host.
The following code is used: /// Ping. CS Namespace saurabhping { Using system; Using system. net; Using system. net. Sockets; /// <Summary> /// Main class: Ping /// </Summary> Class Ping { // Declare several Constants Const int socket_error =-1; Const int ICMP_Echo = 8; /// <Summary> /// Obtain the hostname Parameter /// </Summary> Public static void main (string [] argv) { If (argv. Length = 0) { // If user did not enter any parameter inform him Console. writeline ("Usage: Ping Console. writeline ("Console. writeline ("/R ping the host continuously "); } Else if (argv. Length = 1) { // Just the hostname provided by the user // Call the method "pinghost" and pass the hostname as a parameter Pinghost (argv [0]); } Else if (argv. Length = 2) { // The user provided the hostname and the switch If (argv [1] = "/R ") { // Loop the Ping program While (true) { // Call the method "pinghost" and pass the hostname as a parameter Pinghost (argv [0]); } } Else { // If the user provided some other switch Pinghost (argv [0]); } } Else { // Some error occurred Console. writeline ("error in arguments "); } }
/// <Summary> /// The main method used to obtain the IP address, /// Calculate the response time /// </Summary> Public static void pinghost (string host) { // Declare the iphostentry Iphostentry serverhe, fromhe; Int nbytes = 0; Int dwstart = 0, dwstop = 0; // Initilize a socket of the type ICMP Socket socket = New socket (addressfamily. afinet, sockettype. sockraw, protocoltype. proticmp );
// Get the server endpoint Try { Serverhe = DNS. gethostbyname (host ); } Catch (exception) { Console. writeline ("Host Not Found"); // fail Return; }
// Convert the server ip_endpoint to an endpoint Ipendpoint ipepserver = new ipendpoint (serverhe. Addresslist [0], 0 ); Endpoint epserver = (ipepserver );
// Set the processing ing endpoint to the client machine Fromhe = DNS. gethostbyname (DNS. gethostname ()); Ipendpoint ipendpointfrom = new ipendpoint (fromhe. Addresslist [0], 0 ); Endpoint endpointfrom = (ipendpointfrom );
Int packetsize = 0; Icmppacket packet = new icmppacket (); // Construct the packet to send Packet. type = ICMP_Echo; // 8 Packet. subcode = 0; Packet. checksum = uint16.parse ("0 "); Packet. identifier = uint16.parse ("45 "); Packet. sequencenumber = uint16.parse ("0 "); Int pingdata = 32; // sizeof (icmppacket)-8; Packet. Data = new byte [pingdata]; // Initilize the packet. Data For (INT I = 0; I <pingdata; I ++) { Packet. Data [I] = (byte )'#'; }
// Variable to hold the total packet size Packetsize = pingdata + 8; Byte [] icmp_pkt_buffer = new byte [packetsize]; Int32 Index = 0; // Call a method serialize which counts // The total number of bytes in the packet Index = serialize ( Packet, Icmp_pkt_buffer, Packetsize, Pingdata ); // Error in packet size If (Index =-1) { Console. writeline ("error in making packet "); Return; }
// Now get this critter into a uint16 Array
// Get the half size of the packet Double double_length = convert. todouble (INDEX ); Double dtemp = math. Ceil (double_length/2 ); Int cksum_buffer_length = convert. toint32 (dtemp ); // Create a byte array Uint16 [] cksum_buffer = new uint16 [cksum_buffer_length]; // Code to initialize the uint16 Array Int icmp_header_buffer_index = 0; For (INT I = 0; I <cksum_buffer_length; I ++ ){ Cksum_buffer [I] = Bitconverter. touint16 (icmp_pkt_buffer, icmp_header_buffer_index ); Icmp_header_buffer_index + = 2; } // Call a method which will return a checksum Uint16 u_cksum = checksum (cksum_buffer, cksum_buffer_length ); // Save the checksum to the packet Packet. checksum = u_cksum;
// Now that we have the checksum, serialize the packet again Byte [] sendbuf = new byte [packetsize]; // Again check the packet size Index = serialize ( Packet, Sendbuf, Packetsize, Pingdata ); // If there is a error report it If (Index =-1) { Console. writeline ("error in making packet "); Return; }
Dwstart = system. environment. tickcount; // start timing // Send the pack over the socket If (nbytes = socket. sendto (sendbuf, packetsize, 0, epserver) = socket_error) { Console. writeline ("socket error cannot send packet "); } // Initialize the buffers. The receive buffer is the size of // ICMP header plus the IP header (20 bytes) Byte [] receivebuffer = new byte [1, 256]; Nbytes = 0; // Receive the bytes Bool recd = false; Int timeout = 0;
// Loop for checking the time of the server responding While (! Recd) { Nbytes = socket. receivefrom (receivebuffer, 256, 0, ref endpointfrom ); If (nbytes = socket_error) { Console. writeline ("Host Not responding "); Recd = true; Break; } Else if (nbytes> 0) { Dwstop = system. environment. tickcount-dwstart; // stop timing Console. writeline ("reply from" + epserver. tostring () + "in" + Dwstop + "MS: bytes received" + nbytes ); Recd = true; Break; } Timeout = system. environment. tickcount-dwstart; If (timeout> 1000) { Console. writeline ("time out "); Recd = true; } }
// Close the socket Socket. Close (); } /// <Summary> /// This method get the packet and calculates the total size /// Of the pack by converting it to byte array /// </Summary> Public static int32 serialize (icmppacket packet, byte [] buffer, Int32 packetsize, int32 pingdata) { Int32 cbreturn = 0; // Serialize the struct into the Array Int Index = 0;
Byte [] B _type = new byte [1]; B _type [0] = (packet. type );
Byte [] B _code = new byte [1]; B _code [0] = (packet. subcode );
Byte [] B _cksum = bitconverter. getbytes (packet. checksum ); Byte [] B _id = bitconverter. getbytes (packet. identifier ); Byte [] B _seq = bitconverter. getbytes (packet. sequencenumber );
// Console. writeline ("serialize type "); Array. Copy (B _type, 0, buffer, index, B _type.length ); Index + = B _type.length;
// Console. writeline ("serialize Code "); Array. Copy (B _code, 0, buffer, index, B _code.length ); Index + = B _code.length;
// Console. writeline ("serialize cksum "); Array. Copy (B _cksum, 0, buffer, index, B _cksum.length ); Index + = B _cksum.length;
// Console. writeline ("serialize ID "); Array. Copy (B _id, 0, buffer, index, B _id.length ); Index + = B _id.length;
Array. Copy (B _seq, 0, buffer, index, B _seq.length ); Index + = B _seq.length;
// Copy the data Array. Copy (packet. Data, 0, buffer, index, pingdata ); Index + = pingdata; If (index! = Packetsize/* sizeof (icmppacket )*/){ Cbreturn =-1; Return cbreturn; }
Cbreturn = index; Return cbreturn; } /// <Summary> /// This method has the algorithm to make a checksum /// </Summary> Public static uint16 checksum (uint16 [] buffer, int size) { Int32 cksum = 0; Int counter; Counter = 0;
While (size> 0 ){ Uint16 val = buffer [Counter];
Cksum + = convert. toint32 (buffer [Counter]); Counter + = 1; Size-= 1; }
Cksum = (cksum> 16) + (cksum & 0 xFFFF ); Cksum + = (cksum> 16 ); Return (uint16 )(~ Cksum ); } } // Class ping /// <Summary> /// Class that holds the Pack information /// </Summary> Public class icmppacket { Public byte type; // type of message Public byte subcode; // type of sub code Public uint16 checksum; // ones complement checksum of struct Public uint16 identifier; // identifier Public uint16 sequencenumber; // sequence number Public byte [] data;
} // Class icmppacket }
|