欢迎光临
我们一直在努力

C#下实现ping功能-.NET教程,C#语言

建站超值云服务器,限时71元/月

这段时间一直在学习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();

}

}

}

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » C#下实现ping功能-.NET教程,C#语言
分享到: 更多 (0)

相关推荐

  • 暂无文章