C#论坛-玄机论坛-C#论坛-玄机宝盒-玄机类库-C#

 找回密码
 关闭注册

QQ登录

只需一步,快速开始

查看: 4462|回复: 5

[剑走偏锋] C# ping 类 测试IP是否正常 IP速度 等

[复制链接]
君临 发表于 2015-1-5 15:36:05 | 显示全部楼层 |阅读模式

玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
如有疑问,请加入官方群询问

您需要 登录 才可以下载或查看,没有帐号?关闭注册

x
分享一个ping 的类大多用来测试IP是否正常 IP速度 等.
标准的ICMP报文,而不是调用CMD.

调用方法   返回string 单位(ms):
[mw_shl_code=csharp,true] Pings p = new Pings();[/mw_shl_code]
[mw_shl_code=csharp,true]string Speed = p.PingHost("127.0.0.1");[/mw_shl_code]


[mw_shl_code=csharp,true]using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;

namespace VpnSec.Ro4ters
{
    class Pings
    {
        const int SOCKET_ERROR = -1;
        const int ICMP_ECHO = 8;
        public string PingHost(string host)
        {
            // 声明 IPHostEntry
            IPHostEntry ServerHE, fromHE;
            int nBytes = 0;
            int dwStart = 0, dwStop = 0;

            //初始化ICMP的Socket
            Socket socket =
             new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000);
            // 得到Server EndPoint
            try
            {
                ServerHE = Dns.GetHostByName(host);
            }
            catch (Exception)
            {

                return "没有发现主机";
            }

            // 把 Server IP_EndPoint转换成EndPoint
            IPEndPoint ipepServer = new IPEndPoint(ServerHE.AddressList[0], 0);
            EndPoint epServer = (ipepServer);

            // 设定客户机的接收Endpoint
            fromHE = Dns.GetHostByName(Dns.GetHostName());
            IPEndPoint ipEndPointFrom = new IPEndPoint(fromHE.AddressList[0], 0);
            EndPoint EndPointFrom = (ipEndPointFrom);

            int PacketSize = 0;
            IcmpPacket packet = new IcmpPacket();

            // 构建要发送的包
            packet.Type = ICMP_ECHO; //8
            packet.SubCode = 0;
            packet.CheckSum = 0;
            packet.Identifier = 45;
            packet.SequenceNumber = 0;
            int PingData = 24; // sizeof(IcmpPacket) - 8;
            packet.Data = new Byte[PingData];

            // 初始化Packet.Data
            for (int i = 0; i < PingData; i++)
            {
                packet.Data = (byte)'#';
            }

            //Variable to hold the total Packet size
            PacketSize = 32;
            Byte[] icmp_pkt_buffer = new Byte[PacketSize];
            Int32 Index = 0;
            //again check the packet size
            Index = Serialize(
             packet,
             icmp_pkt_buffer,
             PacketSize,
             PingData);
            //if there is a error report it
            if (Index == -1)
            {
                return "Error Creating Packet";

            }
            // convert into a UInt16 array

            //Get the Half size of the Packet
            Double double_length = Convert.ToDouble(Index);
            Double dtemp = Math.Ceiling(double_length / 2);
            int cksum_buffer_length = Index / 2;
            //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 =
                 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)
            {
                return "Error Creating Packet";

            }

            dwStart = System.Environment.TickCount; // Start timing
            //send the Packet over the socket
            if ((nBytes = socket.SendTo(sendbuf, PacketSize, 0, epServer)) == SOCKET_ERROR)
            {
                return "Socket Error: cannot send Packet";
            }
            // Initialize the buffers. The receive buffer is the size of the
            // ICMP header plus the IP header (20 bytes)
            Byte[] ReceiveBuffer = new Byte[1024];
            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, ref EndPointFrom);//, 0, SocketFlags.None, ref EndPointFrom);
                if (nBytes == SOCKET_ERROR)
                {
                    return "主机没有响应";

                }
                else if (nBytes > 0)
                {
                    dwStop = System.Environment.TickCount - dwStart; // stop timing
                    return dwStop.ToString();//"Reply from " + epServer.ToString() + " in "
                    //+ dwStop + "ms.  Received: " + nBytes + " Bytes.";

                }
                timeout = System.Environment.TickCount - dwStart;
                if (timeout > 1000)
                {
                    return "超时";
                }
            }

            //close the socket
            socket.Close();
            return "";
        }
        /// <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);

            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;

            // 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 += buffer[counter];
                counter += 1;
                size -= 1;
            }

            cksum = (cksum >> 16) + (cksum & 0xffff);
            cksum += (cksum >> 16);
            return (UInt16)(~cksum);
        }
    }
    /// 类结束
    /// <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;

    }
}
[/mw_shl_code]
玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
帖子内网盘失效后请使用下面地址

http://bbs.msdn5.com/forum.php?mod=viewthread&tid=1218
如果失效请联系站长重新分享
回复

使用道具 举报

乔克斯 发表于 2015-1-5 15:37:19 | 显示全部楼层
不错不错
玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
帖子内网盘失效后请使用下面地址

http://bbs.msdn5.com/forum.php?mod=viewthread&tid=1218
如果失效请联系站长重新分享
回复

使用道具 举报

inghot 发表于 2015-1-5 15:37:41 | 显示全部楼层
这个看上去好复杂的样子,估计做了完整的处理。。。
玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
帖子内网盘失效后请使用下面地址

http://bbs.msdn5.com/forum.php?mod=viewthread&tid=1218
如果失效请联系站长重新分享
回复 支持 反对

使用道具 举报

老段啦 发表于 2015-1-5 17:02:23 | 显示全部楼层
这个ping IP 怎么返回的都是0
玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
帖子内网盘失效后请使用下面地址

http://bbs.msdn5.com/forum.php?mod=viewthread&tid=1218
如果失效请联系站长重新分享
回复 支持 反对

使用道具 举报

style 发表于 2016-12-28 17:56:58 | 显示全部楼层
谢谢 分享~~~
玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
帖子内网盘失效后请使用下面地址

http://bbs.msdn5.com/forum.php?mod=viewthread&tid=1218
如果失效请联系站长重新分享
回复

使用道具 举报

Leo 发表于 2019-11-28 15:42:16 | 显示全部楼层
谢谢分享
玄机论坛-专业的C#交流论坛 交流QQ群: 16885911
帖子内网盘失效后请使用下面地址

http://bbs.msdn5.com/forum.php?mod=viewthread&tid=1218
如果失效请联系站长重新分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 关闭注册

本版积分规则

关闭

站长推荐上一条 /2 下一条

QQ|玄机论坛

GMT+8, 2024-4-20 20:44 , Processed in 0.179690 second(s), 16 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表