ping的调用方法如下: Ping mPing=new Ping(); mPing.Pinging(“127.0.0.1“,255,65535); mPing.Receive(); //成功接收返回true,timeout 返回false 全部源代码如下: using System; using System.IO; using System.Net; using System.Net.Sockets; namespace Ping { /// <summary> /// Summary description for Ping. /// </summary> /// // // //IP Header public class IPHDR { public byte VIHL { get{return mVIHL;} set{mVIHL=value;} }private byte mVIHL; public byte TOS { get{return mTOS;} set{mTOS=value;} }private byte mTOS; public short TotLen { get{return mTotLen;} set{mTotLen=value;} }private short mTotLen; public short ID { get{return mID;} set{mID=value;} }private short mID; public short FlagOff { get{return mFlagOff;} set{mFlagOff=value;} }private short mFlagOff; public byte TTL { get{return mTTL;} set{mTTL=value;} }private byte mTTL; public byte Protocol { get{return mProtocol;} set{mProtocol=value;} }private byte mProtocol; public ushort Checksum { get{return mChecksum;} set{mChecksum = value;} }private ushort mChecksum; public ulong iaSrc { get{return miaSrc;} set{miaSrc=../../value;} }private ulong miaSrc; public ulong iaDst { get{return miaDst;} set{miaDst=value;} }private ulong miaDst;
public static string Address(ulong obj) { byte s1=(byte)obj; byte s2=(byte)(obj>>8); byte s3=(byte)(obj>>16); byte s4=(byte)(obj>>24); return String.Format("{0}.{1}.{2}.{3}",s1,s2,s3,s4);//s1+"."+s2+"."+s3+"."+s4; } public void Encode(BinaryWriter writer) { writer.Write(VIHL); writer.Write(TOS); writer.Write((Int16)TotLen); writer.Write((Int16)ID); writer.Write((Int16)FlagOff); writer.Write(TTL); writer.Write(Protocol); writer.Write((UInt16)Checksum); writer.Write((UInt32)iaSrc); writer.Write((UInt32)iaDst);
} public void Decode(BinaryReader reader) { VIHL=reader.ReadByte(); TOS=reader.ReadByte(); TotLen=reader.ReadInt16(); ID=reader.ReadInt16(); FlagOff=reader.ReadInt16(); TTL=reader.ReadByte(); Protocol=reader.ReadByte(); Checksum=reader.ReadUInt16(); iaSrc=../../reader.ReadUInt32(); iaDst=reader.ReadUInt32(); }
} //ICMP Header; public class ICMPHDR { public byte Type { get{return mType;} set{mType=value;} }private byte mType; public byte Code { get{return mCode;} set{mCode=value;} }private byte mCode=0; public ushort Checksum { get{return mChecksum;} set{mChecksum=value;} }private ushort mChecksum=0; public ushort ID { get{return mID;} set{mID=value;} }private ushort mID; public ushort Seq { get{return mSeq;} set{mSeq=value;} }private ushort mSeq; public ulong tmSend { get{return mtmSend;} set{mtmSend=value;} }private ulong mtmSend;
public int nTaskId { get{return mnTaskId;} set{mnTaskId=value;} }private int mnTaskId; public void Encode(BinaryWriter writer) { writer.Write(Type); writer.Write(Code); writer.Write((UInt16)Checksum); writer.Write((UInt16)ID); writer.Write((UInt16)Seq); writer.Write((UInt32)tmSend); writer.Write(nTaskId); } public void Decode(BinaryReader reader) { Type=reader.ReadByte(); Code=reader.ReadByte(); Checksum=reader.ReadUInt16(); ID=reader.ReadUInt16(); Seq=reader.ReadUInt16(); tmSend=reader.ReadUInt32(); nTaskId=reader.ReadInt32(); } public uint Sum() { uint sum=0; sum +=(ushort)(Type+(Code<<8)); sum +=(ushort)ID; sum +=(ushort)Seq; sum +=(ushort)tmSend; sum +=(ushort)(tmSend>>16); sum +=(ushort)nTaskId; sum +=(ushort)(nTaskId>>16); return sum; } } public class ECHOREQUEST { private char[] mChar; public ICMPHDR icmp=new ICMPHDR(); public ECHOREQUEST(int size,char nChar) { mChar=new Char[size]; for(int i=0;i<size;i++) mChar[i]=nChar; } public void Encode(BinaryWriter writer) { chksum(); icmp.Encode(writer); writer.Write(mChar); } /* public void Decode(BinaryReader reader) { icmp.Decode(reader); string s=reader.ReadString(); mChar=s.ToCharArray(); } */ private void chksum() { uint sum=icmp.Sum(); for(int i=0;i<mChar.Length;i+=2) sum +=(ushort)(mChar[i]+(mChar[i+1]<<8)); // sum = (sum >> 16) + (sum & 0xffff); // add hi 16 to low 16 sum += (sum >> 16); // add carry short answer = (short)~sum; // truncate to 16 bits icmp.Checksum=(ushort)answer; } } //ICMP Echo Reply public class ECHOREPLY { public IPHDR ipHdr=null; public ICMPHDR icmpHdr=null; public char[] cFiller; public void Decode(BinaryReader reader) { ipHdr=new IPHDR(); ipHdr.Decode(reader);
icmpHdr=new ICMPHDR(); icmpHdr.Decode(reader);
int bytes=(int)reader.BaseStream.Length; // cFiller=reader.ReadChars(8); cFiller=reader.ReadChars(bytes-36); } } public class StateObject { public Socket workSocket = null; // Client socket. public const int BufferSize = 256; // Size of receive buffer. public byte[] buffer = new byte[BufferSize]; // Receive buffer. // public StringBuilder sb = new StringBuilder();// Received data string. }
public class Ping { Socket socket=null; int m_id; uint m_taskid; uint m_seq; System.Threading.ManualResetEvent recvDone=null; DateTime m_dtSend; public Ping() { m_seq=0; recvDone=new System.Threading.ManualResetEvent(false); socket=new Socket(AddressFamily.InterNetwork,SocketType.Raw,ProtocolType.Icmp); // // TODO: Add constructor logic here // } public bool Pinging(string addr,int id, uint taskid) { try { m_id=id; m_taskid=taskid; Byte[] byReq =FillEchoReq();
//send to
IPEndPoint lep = new IPEndPoint(IPAddress.Parse(addr), 0);
socket.SendTo(byReq,lep); } catch(Exception e) { Console.WriteLine("Send error:"+e.ToString()); return false; }
return true; } private Byte[] FillEchoReq() { m_seq++; if(m_seq>1000) m_seq=1; ECHOREQUEST req=new ECHOREQUEST(8,'E'); req.icmp.Type=8; req.icmp.Code=0; req.icmp.ID=(ushort)m_id; req.icmp.Seq=(ushort)m_seq; req.icmp.nTaskId=(int)m_taskid; m_dtSend=DateTime.Now;
req.icmp.tmSend=(ulong)DateTime.Now.Ticks; MemoryStream stream=new MemoryStream(); BinaryWriter writer=new BinaryWriter(stream); req.Encode(writer);
int toReads=(int)stream.Length; //get Byte array. Byte[] byReq=stream.ToArray();
stream.Close(); return byReq; }
private static uint iocntlCheck(Socket s) {
// Set up the input and output byte arrays. byte[] inValue = BitConverter.GetBytes(0); byte[] outValue = BitConverter.GetBytes(0);
// Check how many bytes have been received. s.IOControl(0x4004667F, inValue, outValue); uint bytesAvail = BitConverter.ToUInt32(outValue, 0); return bytesAvail; } //used to check reply data by sync public bool checkReply() { uint byAvail=iocntlCheck(socket); if(byAvail<=0) return false; try { Byte[] recv=new Byte[byAvail]; socket.Receive(recv); return checkEchoReply(recv,(int)byAvail); } catch(Exception e) { Console.WriteLine(e.ToString()); return false; } } //Directly analyze the byte array.
public bool checkEchoReply1(Byte[] recv,int len) { if(len<36) return false; int ttl=recv[8]; string src=../../recv[12]+"."+recv[13]+"."+recv[14]+"."+recv[15]; string dst=recv[16]+"."+recv[17]+"."+recv[18]+"."+recv[19]; int type=recv[20]; if(type !=0) return false; //24,25, id int id=recv[24]+(recv[25]<<8); if(id !=m_id) return false; //26,27, seq int seq=recv[26]+(recv[27]<<8); //32,33,34,35, task id int taskid=recv[32]+(recv[33]<<8)+(recv[34]<<16)+(recv[35]<<24); if(taskid !=m_taskid) return false; int bytes= len-36;
TimeSpan ts=DateTime.Now-m_dtSend; Console.WriteLine("Reply from {0}: bytes={1},icmp_seq={2},TTL={3},time={4} ms", src,bytes,seq,ttl ,ts.Milliseconds );
return true;
} //use IPHDR, ICMPHDR to analyze replyk data. public bool checkEchoReply(Byte[] recv,int len) { //20bytes ip pack. if(len<36) return false; MemoryStream stream=new MemoryStream(recv,0,len,false); BinaryReader reader=new BinaryReader(stream); ECHOREPLY reply=new ECHOREPLY(); reply.Decode(reader);
stream.Close(); string dst,src; dst=IPHDR.Address(reply.ipHdr.iaDst); src=../../IPHDR.Address(reply.ipHdr.iaSrc);
//type byte type=reply.icmpHdr.Type; //24,25 id int id=reply.icmpHdr.ID; //26,27,seq int seq=reply.icmpHdr.Seq ; //
int bytes= len-36;
//32,33,34,35, task id DateTime dt=new DateTime((long)reply.icmpHdr.tmSend); // Consdt.ToString(); uint taskid=(uint)reply.icmpHdr.nTaskId;//(uint)(recv[32]+(recv[33]<<8)+(recv[34]<<16)+(recv[35]<<24)); TimeSpan ts=DateTime.Now -m_dtSend;//dt; if(type == 0 && id == m_id && m_taskid==taskid) { Console.WriteLine("Reply from {0}: bytes={1},icmp_seq={2},TTL={3},time={4} ms", src,bytes,seq,reply.ipHdr.TTL ,ts.Milliseconds );
return true; } else { // Console.WriteLine("Unknown data,{0},{1},type={2},icmp_seq={3}", // src,dst,type,seq); } return false;
} public bool Receive() { try { recvDone.Reset(); StateObject so=new StateObject(); so.workSocket=socket;
// socket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,5000);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0); EndPoint tempRemoteEP = (EndPoint)sender;
socket.BeginReceiveFrom(so.buffer,0,StateObject.BufferSize,0,ref tempRemoteEP,new AsyncCallback(receiveCallBack),so);
if(!recvDone.WaitOne())//.WaitOne(1000,false)) {//receive timeout Console.WriteLine("Request timed out"); return false; }
} catch(Exception e) { Console.WriteLine("Fail,{0}",e.ToString()); return false; } return true; } public void receiveCallBack(IAsyncResult ar) { try { StateObject obj=(StateObject)ar.AsyncState; Socket sock=obj.workSocket; IPEndPoint ep=new IPEndPoint(IPAddress.Any,0); EndPoint tempEP=(EndPoint)ep; int recvs=sock.EndReceiveFrom(ar,ref tempEP); if(checkEchoReply(obj.buffer,recvs)) recvDone.Set(); else sock.BeginReceiveFrom(obj.buffer,0,StateObject.BufferSize,0,ref tempEP,new AsyncCallback(receiveCallBack),obj); // Console.WriteLine("Address:{0}",((IPEndPoint)tempEP).Address); } catch(Exception e) { Console.WriteLine("CallBack Error:"+e.ToString());
} } public void clear() { socket.Close(); } } }
|
请发表评论