最近在看些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 定義常量 表示...