首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

利用Visual C#实现ICMP网络协议(3)

利用Visual C#实现ICMP网络协议(3)

public class IcmpPacket
{
 private Byte _type ;
 // 类型
 private Byte _subCode ;
 // 代码
 private UInt16 _checkSum ;
 // 校验和
 private UInt16 _identifier ;
 // 识别符
 private UInt16 _sequenceNumber ;
 // 序列号
 private Byte [ ] _data ;
 //选项数据
 public IcmpPacket ( Byte type , Byte subCode , UInt16 checkSum , UInt16 identifier , UInt16 sequenceNumber , int dataSize )
 {
  _type = type ;
  _subCode = subCode ;
  _checkSum = checkSum ;
  _identifier = identifier ;
  _sequenceNumber = sequenceNumber ;
  _data=new Byte [ dataSize ] ;
  //在数据中,写入指定的数据大小
  for ( int i = 0 ; i < dataSize ; i++ )
  {
   //由于选项数据在此命令中并不重要,所以你可以改换任何你喜欢的字符
   _data [ i ] = ( byte )'#' ;
  }
 }
 public UInt16 CheckSum
 {
  get
  {
   return _checkSum ;
  }
  set
  {
   _checkSum=value ;
  }
 }
 //初始化ICMP报文
 public int CountByte ( Byte [ ] buffer )
 {
  Byte [ ] b_type = new Byte [ 1 ] { _type } ;
  Byte [ ] b_code = new Byte [ 1 ] { _subCode } ;
  Byte [ ] b_cksum = BitConverter.GetBytes ( _checkSum ) ;
  Byte [ ] b_id = BitConverter.GetBytes ( _identifier ) ;
  Byte [ ] b_seq = BitConverter.GetBytes ( _sequenceNumber ) ;
  int i = 0 ;
  Array.Copy ( b_type , 0 , buffer , i , b_type.Length ) ;
  i+= b_type.Length ;
  Array.Copy ( b_code , 0 , buffer , i , b_code.Length ) ;
  i+= b_code.Length ;
  Array.Copy ( b_cksum , 0 , buffer ,i , b_cksum.Length ) ;
  i+= b_cksum.Length ;
  Array.Copy ( b_id , 0 , buffer , i , b_id.Length ) ;
  i+= b_id.Length ;
  Array.Copy ( b_seq , 0 , buffer , i , b_seq.Length ) ;
  i += b_seq.Length ;
  Array.Copy ( _data , 0 , buffer , i , _data.Length ) ;
  i += _data.Length ;
  return i ;
 }
 //将整个ICMP报文信息和数据转化为Byte数据包
 public static UInt16 SumOfCheck ( UInt16 [ ] buffer )
 {
  int cksum = 0 ;
  for ( int i = 0 ; i < buffer.Length ; i++ )
   cksum += ( int ) buffer [ i ] ;
   cksum = ( cksum >> 16 ) + ( cksum & 0xffff ) ;
   cksum += ( cksum >> 16 ) ;
   return ( UInt16 ) ( ~cksum ) ;
 }
}

  下列代码是利用IcmpPacket类来创建ICMP报文:

IcmpPacket packet = new IcmpPacket ( 0 , 0 , 0 , 45 , 0 , 4 ) ;

  此代码定义的ICMP报文中的数据段长度为4个字节,所以整个ICMP报文长度为12个字节(即:8+4),而封装此ICMP报文的IP数据包长度就是32个字节(即:8+4+20)。在后面介绍的程序中,从客户端发送的ICMP会显请求报文的数据长度为4个字节,但从服务器介绍到的数据却是32个字节的原因。

  2. 发送封装ICMP回显请求报文的IP数据包:

  发送IP数据包首先要创建一个能够发送封装ICMP回显请求报文的IP数据包Socket实例,然后调用此Socket实例中的"SendTo"方法就可以了。下列代码是创建并初始化一个发送封装ICMP回显请求报文的IP数据包的Socket实例:

Socket socket = new Socket ( AddressFamily.InterNetwork , SocketType.Raw , ProtocolType.Icmp ) ;

  创建初始化Socket实例有三个参数,下面是这些参数的说明:

  第一个参数定义目前网络的寻址方案,目前还是IPV4,所有只有定义为"AddressFamily.InterNetwork"。

  第二个参数定义Socket实例的类型,由于Socket的通讯协议是ICMP,所以选择枚举值"Raw Socket"。

  第三个参数是定义Socket实例有效的协议类型,由于此Socket实例要传送的是ICMP报文,所以选定枚举值为"ProtocolType.Icmp"。

  3.客户机接收封装ICMP应答报文的IP数据包:

  接收服务器端返回的封装ICMP应答报文的IP数据包只需调用Socket实例中的"ReceiveFrom"方法就可以了,具体可参阅下面介绍的程序实现中的代码。

  五.Visual C#实现Ping命令的设计、调试、运行的软件环境

  (1).微软公司视窗2000服务器版

  (2).Visual Studio .Net正式版,.Net FrameWork SDK版本号3705
继承事业,薪火相传
返回列表