第1个回答 2006-12-15
C#:
class Ping
{
const int SOCKET_ERROR = -1;
const int ICMP_ECHO = 8;
public static OnPingLog onpinglog=null;
protected static PingLog plog=new PingLog();
public static void WirteLog(string s)
{
Ping.plog.writelog(s);
if(onpinglog!=null)
{
onpinglog(s);
}
}
public static UInt16 checksum(UInt16[] buffer,int size)
{
Int32 cksum = 0;
int counter = 0;
while (size>0)
{
UInt16 val = buffer[counter];
cksum += Convert.ToInt32(buffer[counter]);
counter++;
size--;
}
cksum = (cksum >> 16)+(cksum & 0xffff);
cksum += (cksum >> 16);
return (UInt16)(~cksum);
}
public static Int32 Serialize( IcmpPacket packet,Byte[] Buffer,Int32 PacketSize,Int32 PingData)
{
Int32 cbReturn = 0;
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;
Array.Copy(packet.Data,0,Buffer,Index,PingData);
Index += PingData;
if(Index != PacketSize)
{
cbReturn = -1;
return cbReturn;
}
cbReturn = Index;
return cbReturn;
}
public static void PingHost(string host)
{
IPHostEntry serverHE,fromHE;
int nBytes = 0;
int dwStart = 0;
int dwStop = 0;
Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Raw,ProtocolType.Icmp);
try
{
//serverHE = Dns.GetHostByName(host);
serverHE = Dns.GetHostByAddress(host.Split(':')[0]);
}
catch(Exception)
{
WirteLog("目标主机" + host + "不存在");
return;
}
//测试端口
// int portNum = 0;
// if(host.Split(':').Length > 1)
// {
// portNum = Int32.Parse(host.Split(':')[1]);
// }
// else
// {
// portNum = 13;
// }
// string hostName = host.Split(':')[0];
// try
// {
// TcpClient client = new TcpClient(hostName, portNum);
// client.Close();
// }
// catch (Exception e)
// {
// WirteLog("错误:" + host + e.Message + "");
// socket.Close();
// return;
// }
IPEndPoint ipepServer;
if(host.Split(':').Length > 1)
{
ipepServer = new IPEndPoint(serverHE.AddressList[0],Int32.Parse(host.Split(':')[1]));
}
else
{
ipepServer = new IPEndPoint(serverHE.AddressList[0],0);
}
EndPoint epServer = (ipepServer);
fromHE = Dns.GetHostByName(Dns.GetHostName());
IPEndPoint ipEndPointFrom;
if(host.Split(':').Length == 1)
{
ipEndPointFrom = new IPEndPoint(fromHE.AddressList[0],0);
}
else
{
ipEndPointFrom = new IPEndPoint(fromHE.AddressList[0],Int32.Parse(host.Split(':')[1]));
}
EndPoint EndPointFrom = (ipEndPointFrom);
int PacketSize = 0;
IcmpPacket packet = new IcmpPacket();
packet.Type = ICMP_ECHO;
packet.SubCode = 0;
packet.CheckSum = UInt16.Parse("0");
packet.Identifier = UInt16.Parse("45");
packet.SequenceNumber = UInt16.Parse("0");
int PingData = 32;
packet.Data = new Byte[PingData];
for(int i=0;i<PingData;i++)
{
packet.Data[i] = (byte)'#';
}
PacketSize = PingData + 8;
Byte[] icmp_pkt_buffer = new Byte[PacketSize];
Int32 Index = 0;
Index = Serialize(packet,icmp_pkt_buffer,PacketSize,PingData);
if(Index == -1)
{
WirteLog("错误(Error in Making Packet)");
return;
}
Double double_length = Convert.ToDouble(Index);
Double dtemp = Math.Ceiling(double_length/2);
int cksum_buffer_length = Convert.ToInt32(dtemp);
UInt16[] cksum_buffer = new UInt16[cksum_buffer_length];
int icmp_header_buffer_index = 0;
for(int i=0;i<cksum_buffer_length;i++)
{
cksum_buffer[i] = BitConverter.ToUInt16(icmp_pkt_buffer,icmp_header_buffer_index);
icmp_header_buffer_index += 2;
}
UInt16 u_cksum = checksum(cksum_buffer,cksum_buffer_length);
packet.CheckSum = u_cksum;
Byte[] sendbuf = new Byte[PacketSize];
Index = Serialize(packet,sendbuf,PacketSize,PingData);
if(Index == -1)
{
WirteLog("错误(Error in Making Packet)");
return;
}
dwStart = System.Environment.TickCount;
if((nBytes = socket.SendTo(sendbuf,PacketSize,0,epServer)) == SOCKET_ERROR)
{
WirteLog("错误(Socket Error can not Sending Packet)");
}
Byte[] ReceiveBuffer = new Byte[256];
nBytes = 0;
bool recd = false;
int timeout = 0;
while(!recd)
{
nBytes = socket.ReceiveFrom(ReceiveBuffer,256,0,ref EndPointFrom);
if(nBytes == SOCKET_ERROR)
{
WirteLog("错误(远程主机没有响应)");
recd = true;
break;
}
else if(nBytes > 0)
{
dwStop = System.Environment.TickCount - dwStart;
WirteLog("成功(Reply from"+epServer.ToString()+":bytes = "+ nBytes.ToString()+"time = "+dwStop +"ms)");
recd = true;
break;
}
timeout = System.Environment.TickCount - dwStart;
if(timeout > 1000)
{
WirteLog("错误(超时)");
recd = true;
}
}
socket.Close();
}
}
public class IcmpPacket
{
public IcmpPacket()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public Byte Type;
public Byte SubCode;
public UInt16 CheckSum;
public UInt16 Identifier;
public UInt16 SequenceNumber;
public Byte[] Data;
}