ping程式的實現

2021-08-22 20:23:29 字數 3455 閱讀 4243

最近在看些windows下網路程式設計問題。看到原始套接字的使用,於是看了ping程式的功能實現。

大部分人用ping命令只是作為檢視另乙個系統的網路連線是否正常的一種簡單方法。這裡我介紹下在windows下實現ping程式的兩種方法。

一是使用原始套接字的方法:

**如下:

#include

#pragmacomment(lib,"ws2_32.lib")

#pragmacomment(lib,"iphlpapi.lib")

typedef

structicmp_hdr

icmp_hdr,*picmp_hdr;

typedef

struct_ipheader//20位元組的ip頭

ipheader,*pipheader;

ushortchecksum(ushort*buffer,intsize)

if(size)

cksum=(cksum>>16)+(cksum&0xffff);

cksum+=(cksum>>16);

return(ushort)(~cksum);

}boolsettimeout(sockets,intntime,boolbrecv)

intmain(intargc,char*argv)

charszdestip[20];

strcpy_s(szdestip,argv[1]);

//初始化套接字

wsadatawsadata;

intwsaset=wsastartup(0x101,&wsadata);

socketsraw=::socket(af_inet,sock_raw,ipproto_icmp);

inta=::getlasterror();

settimeout(sraw,1000,true);

sockaddr_indest;

dest.sin_family=af_inet;

dest.sin_port=htons(0);

dest.sin_addr.s_un.s_addr=inet_addr(szdestip);

//建立icmp封包

charbuff[sizeof(icmp_hdr)+32];

icmp_hdr*picmp=(icmp_hdr*)buff;

//填寫icmp包

picmp->icmp_type=8;

picmp->icmp_code=0;

picmp->icmp_id=(ushort)::getcurrentprocessid();

picmp->icmp_checksum=0;

picmp->icmp_sequence=0;

//填充資料

memset(&buff[sizeof(icmp_hdr)],'e',32);

//開始傳送和接收icmp封包

ushortnseq=0;

charrecvbuf[1024];

sockaddr_infrom;

intnlen=sizeof(from);

while(true)

nret=::recvfrom(sraw,recvbuf,1024,0,(sockaddr*)&from,&nlen);

if(nret==socket_error)

printf("recvfrom()failed:%d\n",::wsagetlasterror());

return-1;

}//下面開始解析接收到的icmp封包

intntick=::gettickcount();

if(nret//接收到的資料中包含ip頭,ip頭大小為20個位元組,所以加20得到icmp頭

icmp_hdr*precvicmp=(icmp_hdr*)(recvbuf+20);//(icmp_hdr*)(recvbuf+sizeof(ipheader));

if(precvicmp->icmp_type!=0)//回顯

if(precvicmp->icmp_id!=::getcurrentprocessid())

printf("%dbytesfrom%s:",nret,inet_ntoa(from.sin_addr));

printf("icmp_seq=%d.",precvicmp->icmp_sequence);

printf("time:%dms",ntick-precvicmp->icmp_timestamp);

printf("\n");

::sleep(1000);

}system("pause");

return0;

}這是使用了原始套接字,實現傳送icmp資料報,實現ping程式。

在linux中的ping使用了這種方式。

這裡是乙個比較完整的關於ping程式介紹的文章:

這是windows下實現的ping程式:

但是在使用windows下實現ping的時候發現使用原始套接字需要管理員許可權,但是windows下使用ping程式並不需要使用管理員許可權。感謝shadowstar

提示了我使用icmpsendecho來實現功能。

下面是使用icmpsendecho的示例**:

#pragmacomment(lib,"ws2_32.lib")

#pragmacomment(lib,"iphlpapi.lib")

int__cdeclmain(intargc,char**argv)

ipaddr=inet_addr(argv[1]);

if(ipaddr==inaddr_none)

hicmpfile=icmpcreatefile();

if(hicmpfile==invalid_handle_value)

replysize=sizeof(icmp_echo_reply)+sizeof(senddata);

replybuffer=(void*)malloc(replysize);

if(replybuffer==null)

dwretval=icmpsendecho(hicmpfile,ipaddr,senddata,sizeof(senddata),

null,replybuffer,replysize,1000);

if(dwretval!=0)

else

printf("\treceivedfrom%s\n",inet_ntoa(replyaddr));

printf("\tstatus=%ld\n",

pechoreply->status);

printf("\troundtriptime=%ldmilliseconds\n",

pechoreply->roundtriptime);

}else

return0;

}此段**需要ws2_32.lib和iphlpapi.lib,包含標頭檔案iphlpapi.h和icmpapi.h

linux下實現的ping程式

一 設計目的 ping程式是我們使用的比較多的用於測試網路連通性的程式。ping程式基於icmp,使用icmp的回送請求和回送應答來工作。由計算機網路課程知道,icmp是基於ip的乙個協議,icmp包通過ip的封裝之後傳遞。課程設計中選取ping程式的設計,其目的是通過ping程式的設計,能初步掌握...

網路程式之ping指令的實現

網路程式之ping指令的實現 ping是用於探測網路的連通性的乙個程式.它在網路程式設計中主要是用到了原始套接字層.用raw程式設計是一件很有意思的事情.因為這可以自已自定義ip位址,自定義資料結構.能做自已想做的事情.是socket中最底層的程式設計技術.ping的原理其實就是自定義乙個報文,傳送...

Socket程式設計之ping程式的實現

標頭檔案部分 導入庫檔案 pragma comment lib,ws2 32.lib 載入標頭檔案 include 建立套接字頭檔案 include include include include include include include using namespace std 定義常量 表示...