Board logo

标题: 利用Visual C#实现ICMP网络协议(5) [打印本页]

作者: yuyang911220    时间: 2015-11-23 22:11     标题: 利用Visual C#实现ICMP网络协议(5)

11. 用下列代码替换Form1.cs文件中的button1组件的Click事件对应的处理代码,下列代码的作用是创建、发送ICMP报文,实现Ping命令:

Private Void Button1_click ( Object Sender , System.eventargs E )
{
 Listbox1.items.clear ( ) ;
 String Hostclient = Textbox1.text ;
 Int K ;
 For ( K = 0 ; K < 3 ; K++ )
 {
  Socket Socket = New Socket ( Addressfamily.internetwork , Sockettype.raw , Protocoltype.icmp ) ;
  Iphostentry Hostinfo ;
  Try
  {
   //解析主机ip入口
   Hostinfo = Dns.gethostbyname ( Hostclient ) ;
  }
  Catch ( Exception )
  {
   //解析主机名错误。
   Listbox1.items.add ( "没有发现此主机!" ) ;
   Return ;
  }
  // 取服务器端主机的30号端口
  Endpoint Hostpoint = ( Endpoint ) New Ipendpoint ( Hostinfo.addresslist[ 0 ] , 30 ) ;
  Iphostentry Clientinfo ;
  Clientinfo = Dns.gethostbyname ( Hostclient ) ;
  // 取客户机端主机的30端口
  Endpoint Clientpoint = ( Endpoint ) New Ipendpoint ( Clientinfo.addresslist[ 0 ] , 30 ) ;
  //设置icmp报文
  Int Datasize = 4 ; // Icmp数据包大小 ;
  Int Packetsize = Datasize + 8 ;//总报文长度
  Const Int Icmp_echo = 8 ;
  Icmppacket Packet = New Icmppacket ( Icmp_echo , 0 , 0 , 45 , 0 , Datasize ) ;
  Byte [ ] Buffer = New Byte [ Packetsize ] ;
  Int Index = Packet.countbyte ( Buffer ) ;
  //报文出错
  If ( Index != Packetsize )
  {
   Listbox1.items.add ( "报文出现问题!" ) ;
   Return ;
  }
  Int Cksum_buffer_length = ( Int ) Math.ceiling ( ( ( Double )index )/ 2 ) ;
  Uint16 [ ] Cksum_buffer = New Uint16 [ Cksum_buffer_length ] ;
  Int Icmp_header_buffer_index = 0 ;
  For ( Int I = 0 ; I < Cksum_buffer_length ; I++ )
  {
   //将两个byte转化为一个uint16
   Cksum_buffer[ I ] = Bitconverter.touint16 ( Buffer , Icmp_header_buffer_index ) ;
   Icmp_header_buffer_index += 2 ;
  }
  //将校验和保存至报文里
  Packet.checksum = Icmppacket.sumofcheck ( Cksum_buffer ) ;
  // 保存校验和后,再次将报文转化为数据包
  Byte [ ] Senddata = New Byte [ Packetsize ] ;
  Index = Packet.countbyte ( Senddata ) ;
  //报文出错
  If ( Index != Packetsize )
  {
   Listbox1.items.add ( "报文出现问题!" ) ;
   Return ;
  }
  Int Nbytes = 0 ;
  //系统计时开始
  Int Starttime = Environment.tickcount ;
  //发送数据包
  If ( ( Nbytes = Socket.sendto ( Senddata , Packetsize , Socketflags.none , Hostpoint ) ) == -1 )
  {
   Listbox1.items.add ( "无法传送报文!" ) ;
  }
  Byte [ ] Receivedata = New Byte[ 256 ] ; //接收数据
  Nbytes = 0 ;
  Int Timeout = 0 ;
  Int Timeconsume = 0 ;
  While ( True )
  {
   Nbytes = Socket.receivefrom ( Receivedata , 256 , Socketflags.none , Ref Clientpoint ) ;
   If ( Nbytes == -1 )
   {
    Listbox1.items.add ( "主机没有响应!" ) ;
    Break ;
   }
   Else If ( Nbytes > 0 )
   {
    Timeconsume = System.environment.tickcount - Starttime ;
    //得到发送报文到接收报文之间花费的时间
    Listbox1.items.add ( "reply From " + Hostinfo.addresslist[ 0 ].tostring ( ) + " In "
+ Timeconsume + "ms :bytes Received " + Nbytes ) ;

    Break ;
   }
   Timeconsume = Environment.tickcount - Starttime ;
   If ( Timeout > 1000 )
   {
    Listbox1.items.add ( "time Out" ) ;
    Break ;
   }
  }
  //关闭套接字
  Socket.close ( ) ;
 }
}




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0