理解协议的方法之一,就是自己实现,即使写的不好,但是理解却是深刻的
    
 using System;
using System;
 using System.Text;
using System.Text;
 using Pierce.AttributeClass;
using Pierce.AttributeClass;
 namespace Pierce.Icmp
namespace Pierce.Icmp


 {
{

 /**//// <summary>
    /**//// <summary>
 /// Icmp:Icmp Protocol
    /// Icmp:Icmp Protocol
 /// </summary>
    /// </summary>
 [LastModified("2005-10-11","Icmp Protocol")]
    [LastModified("2005-10-11","Icmp Protocol")]
 public class Icmp
    public class Icmp

 
     {
{
 private eType type;                            //1 Byte Type
        private eType type;                            //1 Byte Type
 private eCode code;                            //1 Byte Code
        private eCode code;                            //1 Byte Code
 private UInt16 Checksum;                    //2 Bytes CheckSum
        private UInt16 Checksum;                    //2 Bytes CheckSum
 private int Messagesize;                    //Message Size,Include Identify,Seq,Content
        private int Messagesize;                    //Message Size,Include Identify,Seq,Content
 private int Packetsize;                        //Icmp package Size
        private int Packetsize;                        //Icmp package Size
 public  byte[] Message = new byte[1024];    //接收回复的byte[]
        public  byte[] Message = new byte[1024];    //接收回复的byte[]
 private byte[] Data=null;                    //存储Icmp包信息
        private byte[] Data=null;                    //存储Icmp包信息
 private static UInt16 sequence=0;            //顺序号
        private static UInt16 sequence=0;            //顺序号
 private static UInt16 identify=0;            //认证号
        private static UInt16 identify=0;            //认证号
 private string content;                        //发送信息
        private string content;                        //发送信息
 private byte[] byContent;                    //发送信息的数组
        private byte[] byContent;                    //发送信息的数组

 /**//// <summary>
        /**//// <summary>
 /// Icmp Type 枚举
        /// Icmp Type 枚举
 /// </summary>
        /// </summary>
 public enum eType:byte
        public enum eType:byte

 
         {
{
 EchoReply=0,
            EchoReply=0,
 DestinationUnreachable=3,
            DestinationUnreachable=3,
 SourceQuench=4,
            SourceQuench=4,
 Redirect=5,
            Redirect=5,
 EchoRequest=8,
            EchoRequest=8,
 TimeExceeded=11,
            TimeExceeded=11,
 ParameterProblem=12,
            ParameterProblem=12,
 TimeStampRequest=13,
            TimeStampRequest=13,
 TimeStampReply=14,
            TimeStampReply=14,
 InformationRequest=15,
            InformationRequest=15,
 InformationReply=16
            InformationReply=16
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// Icmp Code 枚举
        /// Icmp Code 枚举
 /// </summary>
        /// </summary>
 public enum eCode:byte
        public enum eCode:byte

 
         {
{
 NetworkUnreachable=0,
            NetworkUnreachable=0,
 HostUnreachable=1,
            HostUnreachable=1,
 ProtocolUnreachable=2,
            ProtocolUnreachable=2,
 PortUnreachable=3,
            PortUnreachable=3,
 FragmentationNeededAndDFFlagSet=4,
            FragmentationNeededAndDFFlagSet=4,
 SourceRouteFailed=5,
            SourceRouteFailed=5,
 DestinationNetworkUnknow=6,
            DestinationNetworkUnknow=6,
 DestionationHostUnknow=7,
            DestionationHostUnknow=7,
 SourceHostIsolated=8,
            SourceHostIsolated=8,
 CommunicationWithDestinationNetworkProhibited=9,
            CommunicationWithDestinationNetworkProhibited=9,
 CommunicationWithDestinationHostProhibited=10,
            CommunicationWithDestinationHostProhibited=10,
 NetworkUnreachableForTypeOfService=11,
            NetworkUnreachableForTypeOfService=11,
 HostUnreachableForTypeOfService=12
            HostUnreachableForTypeOfService=12
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 属性,读写,获取,设置Type
        /// 属性,读写,获取,设置Type
 /// </summary>
        /// </summary>
 internal eType Type
        internal eType Type

 
         {
{

 get
            get {return type;}
{return type;}

 set
            set {type=value;}
{type=value;}
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 属性,读写,获取、设置Code
        /// 属性,读写,获取、设置Code
 /// </summary>
        /// </summary>
 internal eCode Code
        internal eCode Code

 
         {
{

 get
            get {return code;}
{return code;}

 set
            set {code=value;}
{code=value;}
 }
        }
 
    

 /**//// <summary>
        /**//// <summary>
 /// 属性,只读,返回认证号
        /// 属性,只读,返回认证号
 /// </summary>
        /// </summary>
 internal static UInt16 Identify
        internal static UInt16 Identify

 
         {
{

 get
            get {return identify;}
{return identify;}
 
            
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 属性,制度,返回序列号
        /// 属性,制度,返回序列号
 /// </summary>
        /// </summary>
 internal static UInt16 Sequence
        internal static UInt16 Sequence

 
         {
{

 get
            get {return sequence;}
{return sequence;}
 
            
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 属性,读写,设置,返回发送内容
        /// 属性,读写,设置,返回发送内容
 /// </summary>
        /// </summary>
 internal string Content
        internal string Content

 
         {
{

 get
            get {return content;}
{return content;}
 set
            set

 
             {
{
 //获取发送信息内容,并转换为字节数组
                //获取发送信息内容,并转换为字节数组
 content=value;
                content=value;
 byContent=Encoding.ASCII.GetBytes(content);
                byContent=Encoding.ASCII.GetBytes(content);
 //获取发送信息长度,包括Identify+Sequence+Content
                //获取发送信息长度,包括Identify+Sequence+Content
 Messagesize=byContent.Length+4;
                Messagesize=byContent.Length+4;
 //因为MessageSize不包括type,code,checksum,所以要+4
                //因为MessageSize不包括type,code,checksum,所以要+4
 Packetsize=Messagesize+4;
                Packetsize=Messagesize+4;    
 //保证是2的整数倍
                //保证是2的整数倍
 
                
 if(IfDivision2(Packetsize)==false)
                if(IfDivision2(Packetsize)==false)

 
                 {
{
 Data = new byte[Packetsize +1];
                    Data = new byte[Packetsize +1];
 }
                }
 else
                else

 
                 {
{
 Data=new byte[Packetsize];
                    Data=new byte[Packetsize];
 }
                }
 }
            }
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 生成认证号
        /// 生成认证号
 /// </summary>
        /// </summary>
 /// <returns>返回认证号</returns>
        /// <returns>返回认证号</returns>
 private UInt16 getIdentify()
        private UInt16 getIdentify()

 
         {
{
 try
            try

 
             {
{
 identify++;
                identify++;
 }
            }
 catch
            catch

 
             {
{
 identify=0;
                identify=0;
 }
            }
 
            
 return identify;
                return identify;
 
            
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 生成顺序号
        /// 生成顺序号
 /// </summary>
        /// </summary>
 /// <returns>返回顺序号</returns>
        /// <returns>返回顺序号</returns>
 private UInt16 getSequence()
        private UInt16 getSequence()

 
         {
{
 try
            try

 
             {
{
 sequence++;
                sequence++;
 }
            }
 catch
            catch

 
             {
{
 sequence=0;
                sequence=0;
 }
            }
 
            
 return sequence;
            return sequence;
 
            
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 获取整个Icmp包的字节数组
        /// 获取整个Icmp包的字节数组
 /// </summary>
        /// </summary>
 /// <returns></returns>
        /// <returns></returns>
 internal byte[] IcmpByteArray()
        internal byte[] IcmpByteArray()

 
         {
{
 //设置checksum的初始值为0,计算实际的Checksum
            //设置checksum的初始值为0,计算实际的Checksum
 UInt16 identi=0;
            UInt16 identi=0;
 UInt16 seq=0;
            UInt16 seq=0;
 this.Checksum=0;
            this.Checksum=0;
 this.Checksum=this.getChecksum(out identi,out seq);
            this.Checksum=this.getChecksum(out identi,out seq);
 //获取Icmp包的数组
            //获取Icmp包的数组
 byte[] byteIcmp=this.getBytes(identi,seq);
            byte[] byteIcmp=this.getBytes(identi,seq);
 //返回Icmp包的数组
            //返回Icmp包的数组
 return byteIcmp;
            return byteIcmp;
 
            
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 属性,只读,获取MessageSize, 包括Identi+Seq+Content,
        /// 属性,只读,获取MessageSize, 包括Identi+Seq+Content,
 /// 读取收到的Icmp包时使用
        /// 读取收到的Icmp包时使用
 /// </summary>
        /// </summary>
 internal int MessageSize
        internal int MessageSize

 
         {
{
 get
            get

 
             {
{
 return Messagesize;
                return Messagesize;
 }
            }
 
        
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// default Constructor
        /// default Constructor
 /// </summary>
        /// </summary>
 internal Icmp()
        internal Icmp()

 
         {
{
 
            
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// Constructor Override,Receive Response and Parse It
        /// Constructor Override,Receive Response and Parse It
 /// Because Received Packet include Ip Packet,so we should get our content from position 20
        /// Because Received Packet include Ip Packet,so we should get our content from position 20
 /// </summary>
        /// </summary>
 /// <param name="data">接收到的IP Package,包含了IP Header共20bytes长度</param>
        /// <param name="data">接收到的IP Package,包含了IP Header共20bytes长度</param>
 /// <param name="size">总长度</param>
        /// <param name="size">总长度</param>    
 internal Icmp(byte[] data, int size)
        internal Icmp(byte[] data, int size)

 
         {
{
 type = (eType)Enum.Parse(typeof(eType),data[20].ToString());
            type = (eType)Enum.Parse(typeof(eType),data[20].ToString());
 
            
 code = (eCode)Enum.Parse(typeof(eCode),data[21].ToString());
            code = (eCode)Enum.Parse(typeof(eCode),data[21].ToString());
 Checksum = BitConverter.ToUInt16(data, 22);            //校验和
            Checksum = BitConverter.ToUInt16(data, 22);            //校验和
 Messagesize = size - 24;                            //Message的长度
            Messagesize = size - 24;                            //Message的长度
 Message=new byte[Messagesize];                        //设置Message长度
            Message=new byte[Messagesize];                        //设置Message长度
 Buffer.BlockCopy(data, 24, Message, 0, Messagesize);
            Buffer.BlockCopy(data, 24, Message, 0, Messagesize);
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 检查所给的参数是否可以被2整除,是:True,否:False
        /// 检查所给的参数是否可以被2整除,是:True,否:False
 /// </summary>
        /// </summary>
 /// <param name="Number">给定参数</param>
        /// <param name="Number">给定参数</param>
 /// <returns>如果是,返回True,不是,返回False</returns>
        /// <returns>如果是,返回True,不是,返回False</returns>
 [LastModified("2005-10-12","计算给定参数是否是2的整数倍")]
        [LastModified("2005-10-12","计算给定参数是否是2的整数倍")]
 private bool IfDivision2(int Number)
        private bool IfDivision2(int Number)

 
         {
{
 int yu=Number%2;
            int yu=Number%2;
 if(yu==0)
            if(yu==0)

 
             {
{
 return true;
                return true;
 }
            }
 else
            else

 
             {
{
 return false;
                return false;
 }
            }
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 把Icmp包转换为byte[],除了checksum的值是0外,其他的都是实际值,
        /// 把Icmp包转换为byte[],除了checksum的值是0外,其他的都是实际值,    
 /// </summary>
        /// </summary>
 /// <param name="identi">认证号</param>
        /// <param name="identi">认证号</param>
 /// <param name="seq">序列号</param>
        /// <param name="seq">序列号</param>
 /// <returns>返回Icmp的字节数组</returns>
        /// <returns>返回Icmp的字节数组</returns>
 [LastModified("2005-10-12","将Checksum=0时,把Icmp包转换为Byte[],发送请求时用")]
        [LastModified("2005-10-12","将Checksum=0时,把Icmp包转换为Byte[],发送请求时用")]
 private byte[] getBytes(UInt16 identi,UInt16 seq)
        private byte[] getBytes(UInt16 identi,UInt16 seq)

 
         {
{
 //设置初始值,如果内容为空,那么设置为空,
            //设置初始值,如果内容为空,那么设置为空,
 //type=0,那么位8,即Echo Request
            //type=0,那么位8,即Echo Request
 //code=0
            //code=0 
 if(content==null)
            if(content==null)

 
             {
{
 content="";
                content="";
 }
            }
 if(type==0)
            if(type==0)

 
             {
{
 type=eType.EchoRequest;
                type=eType.EchoRequest;
 
                
 }
            }
 if(code==0)
            if(code==0)

 
             {
{
 code=eCode.NetworkUnreachable;
                code=eCode.NetworkUnreachable;
 }
            }
 //位移变量
            //位移变量
 int cursor=0;
            int cursor=0;    
 //加入Type
            //加入Type
 Buffer.BlockCopy(BitConverter.GetBytes((byte)type), 0, Data, cursor, 1);
            Buffer.BlockCopy(BitConverter.GetBytes((byte)type), 0, Data, cursor, 1);
 cursor++;
            cursor++;
 //加入Code
            //加入Code
 Buffer.BlockCopy(BitConverter.GetBytes((byte)code), 0, Data, cursor, 1);
            Buffer.BlockCopy(BitConverter.GetBytes((byte)code), 0, Data, cursor, 1);
 cursor++;
            cursor++;
 //加入CheckSum
            //加入CheckSum
 Buffer.BlockCopy(BitConverter.GetBytes(Checksum), 0, Data, cursor, 2);
            Buffer.BlockCopy(BitConverter.GetBytes(Checksum), 0, Data, cursor, 2);
 cursor+=2;
            cursor+=2;
 //加入Message Content的Identify,2 Bytes
            //加入Message Content的Identify,2 Bytes
 Buffer.BlockCopy(BitConverter.GetBytes(identi),0, Data, cursor,2);
            Buffer.BlockCopy(BitConverter.GetBytes(identi),0, Data, cursor,2);
 cursor+=2;
            cursor+=2;
 //加入MessageContent的Sequence,2 Bytes
            //加入MessageContent的Sequence,2 Bytes
 Buffer.BlockCopy(BitConverter.GetBytes(seq),0,Data,cursor,2);
            Buffer.BlockCopy(BitConverter.GetBytes(seq),0,Data,cursor,2);
 cursor+=2;
            cursor+=2;
 //加入content
            //加入content            
 Buffer.BlockCopy
            Buffer.BlockCopy
 (
                (
 byContent,0,Data,cursor,byContent.Length
                            byContent,0,Data,cursor,byContent.Length
 );
                );
 //
            //
 return Data;
            return Data;
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 生成Icmp包的byte[],同时传出认证号和序列号
        /// 生成Icmp包的byte[],同时传出认证号和序列号
 /// </summary>
        /// </summary>
 /// <param name="identi">认证号</param>
        /// <param name="identi">认证号</param>
 /// <param name="seq">序列号</param>
        /// <param name="seq">序列号</param>
 /// <returns>返回的Byte[]</returns>
        /// <returns>返回的Byte[]</returns>
 [LastModified("2005-10-12","把Icmp包装换位Byte[]")]
        [LastModified("2005-10-12","把Icmp包装换位Byte[]")]
 internal byte[] getBytes(out UInt16 identi,out UInt16 seq)
        internal byte[] getBytes(out UInt16 identi,out UInt16 seq)

 
         {
{
 //设置初始值
            //设置初始值
 if(content==null)
            if(content==null)

 
             {
{
 content="";
                content="";
 }
            }
 if(type==0)
            if(type==0)

 
             {
{
 type=eType.EchoRequest;
                type=eType.EchoRequest;
 
                
 }
            }
 if(code==0)
            if(code==0)

 
             {
{
 code=eCode.NetworkUnreachable;
                code=eCode.NetworkUnreachable;
 }
            }
 //位移变量
            //位移变量
 int cursor=0;
            int cursor=0;    
 //加入Type
            //加入Type
 Buffer.BlockCopy(BitConverter.GetBytes((byte)type), 0, Data, cursor, 1);
            Buffer.BlockCopy(BitConverter.GetBytes((byte)type), 0, Data, cursor, 1);
 cursor++;
            cursor++;
 //加入Code
            //加入Code
 Buffer.BlockCopy(BitConverter.GetBytes((byte)code), 0, Data, cursor, 1);
            Buffer.BlockCopy(BitConverter.GetBytes((byte)code), 0, Data, cursor, 1);
 cursor++;
            cursor++;
 //加入CheckSum
            //加入CheckSum
 Buffer.BlockCopy(BitConverter.GetBytes(Checksum), 0, Data, cursor, 2);
            Buffer.BlockCopy(BitConverter.GetBytes(Checksum), 0, Data, cursor, 2);
 cursor+=2;
            cursor+=2;
 //加入Message Content的Identify,2 Bytes
            //加入Message Content的Identify,2 Bytes
 identi=getIdentify();
            identi=getIdentify();
 Buffer.BlockCopy(BitConverter.GetBytes(identi),0, Data, cursor,2);
            Buffer.BlockCopy(BitConverter.GetBytes(identi),0, Data, cursor,2);
 cursor+=2;
            cursor+=2;
 //加入MessageContent的Sequence,2 Bytes
            //加入MessageContent的Sequence,2 Bytes
 seq=getSequence();
            seq=getSequence();
 Buffer.BlockCopy(BitConverter.GetBytes(seq),0,Data,cursor,2);
            Buffer.BlockCopy(BitConverter.GetBytes(seq),0,Data,cursor,2);
 cursor+=2;
            cursor+=2;
 //加入content
            //加入content            
 Buffer.BlockCopy
            Buffer.BlockCopy
 (
                (
 byContent,0,Data,cursor,byContent.Length
                byContent,0,Data,cursor,byContent.Length
 );
                );
 //
            //
 return Data;
            return Data;
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// Method to Calcu CheckSum
        /// Method to Calcu CheckSum
 /// 每16位循环相加,进位加在末尾,和再求反
        /// 每16位循环相加,进位加在末尾,和再求反        
 /// </summary>
        /// </summary>
 /// <param name="identi">传出值的参数,做认证用</param>
        /// <param name="identi">传出值的参数,做认证用</param>
 /// <param name="seq" >传出值的参数,标记序列号</param>
        /// <param name="seq" >传出值的参数,标记序列号</param>
 /// <returns>return UInt16 value</returns>
        /// <returns>return UInt16 value</returns>
 [LastModified("2005-10-12","计算Checksum")]
        [LastModified("2005-10-12","计算Checksum")]
 private UInt16 getChecksum(out UInt16 identi,out UInt16 seq)
        private UInt16 getChecksum(out UInt16 identi,out UInt16 seq)

 
         {
{
 UInt32 chcksm = 0;
            UInt32 chcksm = 0;
 byte[] data = getBytes(out identi,out seq);
            byte[] data = getBytes(out identi,out seq);            
 int index = 0;
            int index = 0;
 //每16位循环相加
            //每16位循环相加
 while ( index < Packetsize)
            while ( index < Packetsize)

 
             {
{
 //把data中的每2个byte,转换为UInt16,然后加到chcksm中
                //把data中的每2个byte,转换为UInt16,然后加到chcksm中
 chcksm += Convert.ToUInt32(BitConverter.ToUInt16(data, index));
                chcksm += Convert.ToUInt32(BitConverter.ToUInt16(data, index));
 index += 2;
                index += 2;
 }
            }
 //chcksm右移16位,然后同chcksm同0xffff相与的值相加
            //chcksm右移16位,然后同chcksm同0xffff相与的值相加
 //和值的小16位同大16位相加,即进位加在末尾
            //和值的小16位同大16位相加,即进位加在末尾
 chcksm = (chcksm >> 16) + (chcksm & 0xffff);
            chcksm = (chcksm >> 16) + (chcksm & 0xffff);
 //chchsm在加chcksm右移16位的值
            //chchsm在加chcksm右移16位的值
 //同样是保证进位加在末尾
            //同样是保证进位加在末尾
 chcksm += (chcksm >> 16);
            chcksm += (chcksm >> 16);
 //chchsm取反,转换为UInt16
            //chchsm取反,转换为UInt16
 return (UInt16)(~chcksm);
            return (UInt16)(~chcksm);
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 计算整个Icmp包的Uint16值,如果为0,说明包没有出现传输错误,
        /// 计算整个Icmp包的Uint16值,如果为0,说明包没有出现传输错误,
 /// 因为Checksum的值为其他字段的值的和再求反,所以如果在加上Checksum,
        /// 因为Checksum的值为其他字段的值的和再求反,所以如果在加上Checksum,
 /// 那么得到全1的byte,再求反,结果为0
        /// 那么得到全1的byte,再求反,结果为0
 /// </summary>
        /// </summary>
 /// <param name="data">接收到的数组</param>
        /// <param name="data">接收到的数组</param>
 /// <param name="packetsize">数组长度</param>
        /// <param name="packetsize">数组长度</param>
 /// <returns></returns>
        /// <returns></returns>
 [LastModified("205-10-13","检验收到的数组传输中是否发生错误")]
        [LastModified("205-10-13","检验收到的数组传输中是否发生错误")]
 internal UInt16 CalcuIcmpPack(byte[] data,int packetsize)
        internal UInt16 CalcuIcmpPack(byte[] data,int packetsize)

 
         {
{
 UInt32 chcksm = 0;
            UInt32 chcksm = 0;                
 int index = 0;
            int index = 0;
 //每16位循环相加
            //每16位循环相加
 while ( index < packetsize)
            while ( index < packetsize)

 
             {
{
 //把data中的每2个byte,转换为UInt16,然后加到chcksm中
                //把data中的每2个byte,转换为UInt16,然后加到chcksm中
 chcksm += Convert.ToUInt32(BitConverter.ToUInt16(data, index));
                chcksm += Convert.ToUInt32(BitConverter.ToUInt16(data, index));
 index += 2;
                index += 2;
 }
            }
 //chcksm右移16位,然后同chcksm同0xffff相与的值相加
            //chcksm右移16位,然后同chcksm同0xffff相与的值相加
 //和值的小16位同大16位相加,即进位加在末尾
            //和值的小16位同大16位相加,即进位加在末尾
 chcksm = (chcksm >> 16) + (chcksm & 0xffff);
            chcksm = (chcksm >> 16) + (chcksm & 0xffff);
 //chchsm在加chcksm右移16位的值
            //chchsm在加chcksm右移16位的值
 //同样是保证进位加在末尾
            //同样是保证进位加在末尾
 chcksm += (chcksm >> 16);
            chcksm += (chcksm >> 16);
 //chchsm取反,转换为UInt16
            //chchsm取反,转换为UInt16
 return (UInt16)(~chcksm);
            return (UInt16)(~chcksm);
 }
        }
 }
    }
 }
}

以上是协议的实现,下面是协议的使用
 using System;
using System;
 using System.Net;
using System.Net;
 using System.Net.Sockets;
using System.Net.Sockets;
 using System.Text;
using System.Text;
 using Pierce.AttributeClass;
using Pierce.AttributeClass;
 namespace Pierce.Icmp
namespace Pierce.Icmp


 {
{

 /**//// <summary>
    /**//// <summary>
 /// UseIcmp :使用Icmp协议
    /// UseIcmp :使用Icmp协议
 /// </summary>
    /// </summary>
 [LastModified("2005-10-13","使用Icmp协议")]
    [LastModified("2005-10-13","使用Icmp协议")]
 public class UseIcmp
    public class UseIcmp

 
     {
{
 private Socket host;            //Socket连接
        private Socket host;            //Socket连接
 private int receiveTime;        //接收时间上限
        private int receiveTime;        //接收时间上限
 private int sendTime;            //发送时间上限
        private int sendTime;            //发送时间上限

 /**//// <summary>
        /**//// <summary>
 /// 属性,读写,接收时间上限
        /// 属性,读写,接收时间上限
 /// </summary>
        /// </summary>
 public int ReceiveTime
        public int ReceiveTime

 
         {
{

 get
            get {return receiveTime;}
{return receiveTime;}
 set
            set

 
             {
{
 receiveTime=value;
                receiveTime=value;
 host.SetSocketOption(SocketOptionLevel.Socket,
                host.SetSocketOption(SocketOptionLevel.Socket,
 SocketOptionName.ReceiveTimeout, receiveTime);
                    SocketOptionName.ReceiveTimeout, receiveTime);
 }
            }
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 属性,读写,发送时间上限
        /// 属性,读写,发送时间上限
 /// </summary>
        /// </summary>
 public int SendTime
        public int SendTime

 
         {
{
 get
            get

 
             {
{
 return sendTime;
                return sendTime;
 }
            }
 set
            set

 
             {
{
 sendTime=value;
                sendTime=value;
 host.SetSocketOption(SocketOptionLevel.Socket,
                host.SetSocketOption(SocketOptionLevel.Socket,
 SocketOptionName.SendTimeout, sendTime);
                    SocketOptionName.SendTimeout, sendTime);
 }
            }
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 构造函数,初始化Socket
        /// 构造函数,初始化Socket
 /// </summary>
        /// </summary>
 public UseIcmp()
        public UseIcmp()

 
         {
{
 host = new Socket(AddressFamily.InterNetwork, SocketType.Raw,
            host = new Socket(AddressFamily.InterNetwork, SocketType.Raw,
 ProtocolType.Icmp);
                ProtocolType.Icmp);
 }
        }

 /**//// <summary>
        /**//// <summary>
 /// 给指定地址,发送指定内容的Icmp包,并接受恢复
        /// 给指定地址,发送指定内容的Icmp包,并接受恢复
 /// 如果收到恢复,那么返回True,否则,返回False
        /// 如果收到恢复,那么返回True,否则,返回False
 /// </summary>
        /// </summary>
 /// <param name="Ip">指定Ip地址</param>
        /// <param name="Ip">指定Ip地址</param>
 /// <param name="Content">指定发送信息</param>
        /// <param name="Content">指定发送信息</param>
 /// <returns>返回值</returns>
        /// <returns>返回值</returns>
 public bool SendIcmp(string Ip,string Content)
        public bool SendIcmp(string Ip,string Content)

 
         {
{
 bool ifOk=false;                    //是否成功
            bool ifOk=false;                    //是否成功
 
            
 int recv;                            //接收到的字节数
            int recv;                            //接收到的字节数
 
        
 //目的信息
            //目的信息
 IPEndPoint iep = new IPEndPoint(IPAddress.Parse(Ip), 0);
            IPEndPoint iep = new IPEndPoint(IPAddress.Parse(Ip), 0);
 EndPoint ep = (EndPoint)iep;
            EndPoint ep = (EndPoint)iep;
 //设置Type,Code和CheckSum的初始值
            //设置Type,Code和CheckSum的初始值
 Icmp packet = new Icmp();
            Icmp packet = new Icmp();
 packet.Type = Pierce.Icmp.Icmp.eType.EchoRequest;
            packet.Type = Pierce.Icmp.Icmp.eType.EchoRequest;        
 packet.Code = Pierce.Icmp.Icmp.eCode.NetworkUnreachable;
            packet.Code = Pierce.Icmp.Icmp.eCode.NetworkUnreachable;                
 packet.Content=Content;
            packet.Content=Content;
 
    
 //发送信息的字节内容
            //发送信息的字节内容
 byte[] icmpbyte=packet.IcmpByteArray();
            byte[] icmpbyte=packet.IcmpByteArray();            
 host.SendTo(icmpbyte, icmpbyte.Length, SocketFlags.None, iep);
            host.SendTo(icmpbyte, icmpbyte.Length, SocketFlags.None, iep);
 byte[] data = new byte[1024];
            byte[] data = new byte[1024];
 try
            try

 
             {
{                
 recv = host.ReceiveFrom(data, ref ep);
                recv = host.ReceiveFrom(data, ref ep);
 }
            } 
 catch
            catch 

 
             {
{
 
                
 host.Close();
                host.Close();
 return ifOk;
                return ifOk;
 }
            }
 //接收回复
            //接收回复
 Icmp response=null;
            Icmp response=null;
 try
            try

 
             {
{
 response = new Icmp(data, recv);
                response = new Icmp(data, recv);
 }
            }
 catch
            catch

 
             {
{
 
                
 host.Close();
                host.Close();
 return ifOk;
                return ifOk;
 }
            }
 //检验接收到的包是否出现错误
            //检验接收到的包是否出现错误
 UInt16 sum=response.CalcuIcmpPack(data,recv);
            UInt16 sum=response.CalcuIcmpPack(data,recv);
 if(sum!=0)
            if(sum!=0)

 
             {
{
 
            
 host.Close();
                host.Close();
 return ifOk;
                return ifOk;
 }
            }

 int Identifier = BitConverter.ToInt16(response.Message, 0);
            int Identifier = BitConverter.ToInt16(response.Message, 0);
 int Sequence = BitConverter.ToInt16(response.Message, 2);
            int Sequence = BitConverter.ToInt16(response.Message, 2);        
 string stringData = Encoding.ASCII.GetString(response.Message,
            string stringData = Encoding.ASCII.GetString(response.Message,
 4, response.MessageSize - 4);
                4, response.MessageSize - 4);
 if( response.Type==Icmp.eType.EchoReply &&
            if( response.Type==Icmp.eType.EchoReply &&
 Icmp.Identify==Identifier && Icmp.Sequence==Sequence &&
                Icmp.Identify==Identifier && Icmp.Sequence==Sequence && 
 packet.Content==Content)
                packet.Content==Content)

 
             {
{
 ifOk=true;
                ifOk=true;
 }
            }        
 
            
 host.Close();
            host.Close();
 return ifOk;
            return ifOk;
 }
        }
 }
    }
 }
}
