C# Source Code: How to Ping a computer using .NET Sockets
[
Home
|
Contents
|
Search
|
Reply
| Previous | Next ]
C# Source Code
How to Ping a computer using .NET Sockets
By:
Andrew Baker
Email (spam proof):
Email the originator of this post
Date:
Tuesday, October 30, 2007
Hits:
3070
Category:
Sockets/Internet/Remote Comms
Article:
Below is the C# source code demonstrating how to Ping a computer using .NET sockets. using System; using System.Net.Sockets; using System.Net; class PingExample { ///
/// The main entry point for the application. ///
[STAThread] static void Main(string[] args) { int timeToReplyMs = Ping("MYMACHINENAME",10000); } #region Ping Method ///
/// Pings a host and returns the time taken for the host to respond (given the host name or IP address of the host to ping). ///
///
The host (machine name or IP address) to ping. ///
The ping timeout in ms (zero represents infinite). ///
Returns the time in milliseconds to receive a response from the host.
public static int Ping(string host, int timeout) { IPHostEntry ipHost = Dns.GetHostByName(host); // Ping the server return Ping(ipHost, timeout); } ///
/// Pings a host and returns the time taken for the host to respond. ///
///
The host to ping. ///
The ping timeout in ms (zero represents infinite). ///
Returns the time in milliseconds to receive a response from the host.
public static int Ping(IPHostEntry host, int timeout) { // Declare some Constant Variables const int SOCKET_ERROR = -1; const int ICMP_ECHO = 8; int timeTaken; // Declare the IPHostEntry if (host == null) { throw new ArgumentNullException("host","The host to ping must be specified."); } Socket socket = null; try { // Initilize a Socket of the Type ICMP socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp); // Convert to the first Ip address from the host to an endpoint IPEndPoint ipepServer = new IPEndPoint(host.AddressList[0], 0); EndPoint epServer = (ipepServer); // Set the receiving endpoint to the client machine IPHostEntry localHost; localHost = Dns.GetHostByName(Dns.GetHostName()); IPEndPoint ipEndPointFrom = new IPEndPoint(localHost.AddressList[0], 0); EndPoint EndPointFrom = (ipEndPointFrom); int packetSize; IcmpPacket packet = new IcmpPacket(); // Construct the echo packet packet.Type = ICMP_ECHO; //8 packet.SubCode = 0; packet.CheckSum = UInt16.Parse("0"); packet.Identifier = UInt16.Parse("45"); packet.SequenceNumber = UInt16.Parse("0"); int pingDataSize = 32; // sizeof(IcmpPacket) - 8; packet.Data = new Byte[pingDataSize]; // Initilize the Packet.Data for (int i = 0; i < pingDataSize; i++) { packet.Data[i] = (byte)'#'; } // Variable to hold the total Packet size packetSize = pingDataSize + 8; Byte [] icmpPacketBuffer = new Byte[ packetSize ]; int totalPacketSize; // Call Serialize, which counts the total number of Bytes in the Packet totalPacketSize = _SerializePacket( packet, icmpPacketBuffer, packetSize, pingDataSize ); // Error in Packet Size if( totalPacketSize == -1 ) { // Throw serialization exception throw new ApplicationException("Error serializing packet buffer"); } // Get the packet into a UInt16 array // Get the Half size of the Packet Double packetSizeDouble = Convert.ToDouble(totalPacketSize); Double halfPacketSizeDouble = Math.Ceiling( packetSizeDouble / 2); int checkSumBufferLength = Convert.ToInt32(halfPacketSizeDouble); // Create a Byte Array UInt16 [] checkSumBuffer = new UInt16[checkSumBufferLength]; // Code to initilize the Uint16 array int icmpHeaderBufferIndex = 0; for( int i = 0; i < checkSumBufferLength; i++ ) { checkSumBuffer[i] = BitConverter.ToUInt16(icmpPacketBuffer,icmpHeaderBufferIndex); icmpHeaderBufferIndex += 2; } // Call a method which will return a checksum UInt16 unsignedCheckSum = _CalcChecksum(checkSumBuffer, checkSumBufferLength); // Save the checksum to the Packet packet.CheckSum = unsignedCheckSum; // Have the checksum, serialize the packet again Byte [] sendbuf = new Byte[ packetSize ]; // Check the packet size totalPacketSize = _SerializePacket( packet, sendbuf, packetSize, pingDataSize ); if( totalPacketSize == -1 ) { // Throw serialization exception throw new ApplicationException("Error serializing packet buffer"); } // Start timing int dwStart = Environment.TickCount; // Send the Packet if (socket.SendTo(sendbuf, packetSize, 0, epServer) == SOCKET_ERROR) { throw new ApplicationException("Failed to send packet to " + host.HostName + "."); } // Initialize the buffers. The receive buffer is the size of the // ICMP header plus the IP header (20 bytes) Byte [] arrayBytesReceived = new Byte[256]; // Loop for checking the time of the server responding while(true) { int nBytes = socket.ReceiveFrom(arrayBytesReceived, 256, 0, ref EndPointFrom); timeTaken = Environment.TickCount - dwStart; if (nBytes == SOCKET_ERROR) { throw new ApplicationException("Failed to receive response to echo packet from " + host.HostName + "."); } else if( nBytes>0 ) { // Received message // int dwStop = Environment.TickCount - dwStart; // Console.WriteLine("Reply from " + epServer.ToString() + " in " + dwStop + "MS :Bytes Received" + nBytes); break; } // Default to a one second timeout if( timeTaken > timeout && timeout > 0 ) { throw new ApplicationException("Ping to " + host.HostName + " timed out after " + timeout + " milliseconds."); } } } finally { if ( socket != null ) { // close the socket socket.Shutdown( SocketShutdown.Both ); socket.Close(); } } return timeTaken; } #region Private Methods ///
/// This method get the Packet and calculates the total size /// of the Pack by converting it to byte array ///
private static int _SerializePacket( IcmpPacket packet, Byte [] Buffer, int PacketSize, int PingData ) { int cbReturn; // 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; } ///
/// This Method has the algorithm to make a checksum ///
private static UInt16 _CalcChecksum( UInt16[] buffer, int size ) { int cksum = 0; int counter; counter = 0; while ( size > 0 ) { UInt16 val = buffer[counter]; cksum += Convert.ToInt32( val ); counter += 1; size -= 1; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >> 16); return (UInt16)(~cksum); } #endregion Private Methods #region IcmpPacket Class (Private) ///
/// Class that holds the Pack information. ///
private class IcmpPacket { ///
/// Type of message ///
public Byte Type; ///
/// Type of sub code ///
public Byte SubCode; ///
/// Complement checksum of struct ///
public UInt16 CheckSum; ///
/// Identifier ///
public UInt16 Identifier; ///
/// Sequence number ///
public UInt16 SequenceNumber; ///
/// The data ///
public Byte[] Data; } #endregion IcmpPacket Class (Private) } #endregion
Terms and Conditions
Support this site
Download a trial version of the best FTP application on the internet