分享
 
 
 

C#下实现ping功能

王朝c#·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

这段时间一直在学习C#, 以前一直搞网络的,还是从Ping程序的实现写起吧.

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();

}

}

}

呵呵,写的简单了点,大家可以先把code 复制下来,自己试试就一切ok...

欢迎来信交流, email/MSN:wugy006#163.net

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有