//---------------------------------------------------------------------------
#include <vcl.h>
#include "Unit1.h"
#include <stdio.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
#pragma comment(lib,"ws2_32.lib")
USHORT checksum(USHORT* buff,int size)
{
ULONG chksum=0;
while(size>1) //以双字为单位
{
chksum+=*buff++;
size-=2;
}
if(size==1)//为奇数
{
chksum+=*(UCHAR*)buff;
}
chksum=(chksum>>16)+(chksum&0xffff);//高16位+低16位
chksum+=(chksum>>16);
return (USHORT)(~chksum);
}
bool SetTimeOut(SOCKET s,int nRetime,bool bSetRecv)
{
int ret=setsockopt(s,SOL_SOCKET,bSetRecv?SO_RCVTIMEO:SO_SNDTIMEO,(char*)&nRetime,sizeof(nRetime));
return ret!=SOCKET_ERROR;
}
int main(int argc, char* argv[])
{
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)==SOCKET_ERROR)
{
WSACleanup();
return -1;
}
SOCKET s;
if(argc==2)
{
char destaddr[32]="";
if(argv[1][0]>='0'&&argv[1][0]<='9')
strncpy(destaddr,argv[1],32);
else //域名解析
{
hostent *hostaddr=gethostbyname(argv[1]);
in_addr addr;
if(!hostaddr)
return -1;
memmove(&addr,hostaddr->h_addr_list[0],4);
strncpy(destaddr,inet_ntoa(addr),32);
}
s=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
SetTimeOut(s,1000,True);
sockaddr_in dest;
dest.sin_family=AF_INET;
dest.sin_addr.S_un.S_addr=inet_addr(destaddr);
char buff[sizeof(ICMPHeader)+32]="";
ICMPHeader *pICMP=(ICMPHeader*)buff;
pICMP->icmp_type=8;
pICMP->icmp_code=0;
pICMP->icmp_id=(USHORT)::GetCurrentProcessId();
pICMP->icmp_sequence=0;
USHORT nSeq=0;
CHAR recvBuf[1024]="";
sockaddr_in from;
int nLen=sizeof(from);
printf("/nICMP Package test.../n");
Sleep(1000);
while(True)
{
static int nCount=0;
int nRet;
if(nCount++==4)
break;
pICMP->icmp_checksum=0;
pICMP->icmp_timestamp=::GetTickCount();
pICMP->icmp_sequence=nSeq++;
pICMP->icmp_checksum=checksum((USHORT*)buff,sizeof(ICMPHeader)+32);
nRet=::sendto(s,buff,sizeof(ICMPHeader)+32,0,(SOCKADDR*)&dest,sizeof(dest));
if(nRet==SOCKET_ERROR)
{
printf("sendto() failed:%d/n",WSAGetLastError());
return -1;
}
nRet=::recvfrom(s,recvBuf,1024,0,(SOCKADDR*)&from,&nLen);
if(nRet==SOCKET_ERROR)
{
if(WSAGetLastError()==WSAETIMEDOUT)//超时
{
printf("timed out/n");
continue;
}
printf("recvfrom() failed:%d/n",WSAGetLastError());
return -1;
}
int nTick=::GetTickCount();
if(nRet<sizeof(IPHeader)+sizeof(ICMPHeader))
{
printf("Too few bytes from %s /n",inet_ntoa(from.sin_addr));
}
IPHeader *pRecvIP=(IPHeader*)(recvBuf);
ICMPHeader *pRecvICMP=(ICMPHeader*)(recvBuf+sizeof(IPHeader));
if(pRecvICMP->icmp_type!=0) //返回不是回显
{
printf("nonecho type %d recvd /n",pRecvICMP->icmp_type);
return -1;
}
if(pRecvICMP->icmp_id!=::GetCurrentProcessId())
{
printf(" someone else's packet!/n");
return -1;
}
printf("%d byte from %s:",nRet,inet_ntoa(from.sin_addr));
printf(" icmp_seq=%d,",pRecvICMP->icmp_sequence);
printf(" time=%dms,",nTick-pRecvICMP->icmp_timestamp);
printf(" TTL=%d. /n",pRecvIP->ipTTL);
Sleep(1000);
}
}
closesocket(s);
WSACleanup();
return 0;
}
//---------------------------------------------------------------------------
ICMP-ping源码
原创
©著作权归作者所有:来自51CTO博客作者mb61d995c26a1bb的原创作品,请联系作者获取转载授权,否则将追究法律责任
上一篇:结束进程的几种方法
下一篇:IOCP网络模型基本步骤
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
ping 原理与ICMP协议
【转】ping 原理与ICMP协议ping 的原理 ping 程序是用来探测主机到主机之间是否可通信,
路由器 网络 网络协议 工具 windows -
ICMP Ping Traceroute代码意思
ICMP-type values. ICMP Type Literal 0
ICMP traceroute