标签:
const int SOCKET_ERROR = -1; const int ICMP_ECHO = 8; public string PingHost(string host) { IPHostEntry serverHE, fromHE; Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 3000); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 3000); try { serverHE = Dns.GetHostEntry(host); } catch (Exception) { return "Host not found"; } //用IP地址和端口号构造IPEndPoint对象 EndPoint epServer = new IPEndPoint(serverHE.AddressList[0], 1555); fromHE = Dns.GetHostEntry(Dns.GetHostName()); //Dns.GetHostName()获取本地计算机的主机名 //提供的 AddressFamily InterNetworkV6 的终结点对于此套接字无效,请改用 InterNetwork。 ///改为 IPV4 EndPoint EndPointFrom = new IPEndPoint(fromHE.AddressList[1], 80); int PacketSize = 0; IcmpPacket packet = new IcmpPacket(); 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; packet.Data = new Byte[PingData]; //初始化数据包 for (int i = 0; i < PingData; i++) { packet.Data[i] = (byte)‘#‘; } PacketSize = PingData + 8; Byte[] icmp_pkt_buffer = new Byte[PacketSize]; Int32 Index = 0; Index = Serialize(packet, icmp_pkt_buffer, PacketSize, PingData); if (Index == -1) { return "Error Creating Packet"; } Double double_length = Convert.ToDouble(Index); Double dtemp = Math.Ceiling(double_length / 2); int cksum_buffer_length = Convert.ToInt32(dtemp); //创建一个字节数组 UInt16[] cksum_buffer = new UInt16[cksum_buffer_length]; 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; } UInt16 u_cksum = CheckSum(cksum_buffer, cksum_buffer_length); packet.CheckSum = u_cksum; Byte[] sendbuf = new Byte[PacketSize]; //再次校验包的尺寸 Index = Serialize(packet, sendbuf, PacketSize, PingData); if (Index == -1) { return "Error Creating Packet"; } int dwStart = 0, dwStop = 0; dwStart = System.Environment.TickCount; // Start timing int nBytes = 0; if ((nBytes = socket.SendTo(sendbuf, PacketSize, 0, epServer)) == SOCKET_ERROR) { return "Socket Error: cannot send Packet"; } Byte[] ReceiveBuffer = new Byte[256]; nBytes = 0; bool recd = false; int timeout = 0; while (!recd) { try { //接收数据 nBytes = socket.ReceiveFrom(ReceiveBuffer, 256, SocketFlags.None, ref EndPointFrom); if (nBytes == SOCKET_ERROR) { return "Host not Responding"; } else if (nBytes > 0) { dwStop = System.Environment.TickCount - dwStart; // stop timing return "Reply from " + epServer.ToString() + " in " + dwStop + "ms. Received: " + nBytes + " Bytes."; } timeout = System.Environment.TickCount - dwStart; if (timeout > 3000) { return "Time Out"; } } catch (SocketException e) { return "Time Out"; } } //关闭连接 socket.Close(); return ""; } public static Int32 Serialize(IcmpPacket packet, Byte[] Buffer, Int32 PacketSize, Int32 PingData) { Int32 cbReturn = 0; 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); Array.Copy(b_type, 0, Buffer, Index, b_type.Length); Index += b_type.Length; Array.Copy(b_code, 0, Buffer, Index, b_code.Length); Index += b_code.Length; Array.Copy(b_cksum, 0, Buffer, Index, b_cksum.Length); Index += b_cksum.Length; 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; //复制数据 Array.Copy(packet.Data, 0, Buffer, Index, PingData); Index += PingData; if (Index != PacketSize) { cbReturn = -1; return cbReturn; } cbReturn = Index; return cbReturn; } /// <summary> /// 校验方法 /// </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; } //右移16位 cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >> 16); return (UInt16)(~cksum);//二进制取反:按位求补 } public class IcmpPacket { public Byte Type; public Byte SubCode; public UInt16 CheckSum; public UInt16 Identifier; public UInt16 SequenceNumber; public Byte[] Data; }
标签:
原文地址:http://www.cnblogs.com/wjshan0808/p/4226716.html