根據Ping命令的執行過程,可以把Ping命令分成三個主要的步驟:
1. 定義ICMP報文。
2. 客戶機發送封裝ICMP回顯請求報文的IP數據包。
3. 客戶機接收封裝ICMP應答報文的IP數據包。
解決了上述三個步驟,Visual C#實現Ping命令就基本可以完成了。下面是這三個步驟的具體的解決方法。
1. 定義ICMP報文:
根據圖05所示的ICMP報文組成結構,定義了一個類--IcmpPacket類。IcmpPacket類通過實例化就能夠得到ICMP報文。下面代碼是定義IcmpPacket類:
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 ) ;
}
}