码迷,mamicode.com
首页 > 其他好文 > 详细

Ping

时间:2015-01-15 17:39:12      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

        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;

    }

 

Ping

标签:

原文地址:http://www.cnblogs.com/wjshan0808/p/4226716.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!