源代码如下:
ping.h
#pragma pack(1)
//#define u_char unsigned char
//#define u_short unsigned short
#include
#define ICMP_ECHOREPLY 0
#define ICMP_ECHOREQ 8
//
typedef struct tagIPDR
{
u_char VIHL;//版本和类型
u_char TOS;//服务质量
u_char shortTotLen;//长度
u_char shortID;//编号
u_char shortFlagOff;//分片,Fragment
u_char TTL;//生存时间
u_char Protocol;//协议类型
u_short Checksum;//校验和
struct in_addr iaSrc;//源地址
struct in_addr isDet;//目的地址
}IPHDR,*PIPHDR;//RFC791 的IP协议头类型
typedef struct tagICMP
{
u_char Type;//类型
u_char Code;//代号
u_short Checksum;//校验号
u_short ID;//标识号
u_short Seq;//列号
char Data;//数据信息
}ICMPHDR,*PICMPHDR;//RFC 792 ICMP协议头
/
#define REQ_DATASIZE 32
typedef struct tagECHOREQUEST
{
ICMPHDR icmpHdr;//ICMP协议头
DWORD dwTime;//数据传输时间
char cData[REQ_DATASIZE];//传输数据
}ECHOREQUEST,*PECHOREQUEST;//请求回传的数据长度
///
typedef struct tagECHOREPLY
{
IPHDR ipHdr;
ECHOREQUEST echoRequest;
char cFiler[256];
}ECHOREPLY,*PECHOREPLY;//回送请求报文
#pragma pack()
ping.cpp
#include "ping.h"
#include
#include
#include
DWORD time;
void Ping(LPCSTR pstrHost);//ping 指令函数;
void ReportError(LPCSTR psrtFrom);
int WaitForEchoReply(SOCKET s);
int SendEchoRequest(SOCKET,LPSOCKADDR_IN);
DWORD RecvEchoReply(SOCKET,LPSOCKADDR_IN,char*);
u_short in_cksum(u_short *addr,int len);
void main()
{
WSADATA wsaData;
WORD version=MAKEWORD(1,1);
char pstrHost[20];
if(WSAStartup(version,&wsaData))
{
printf("初始化协议栈错误\n");
getchar();
return ;
}
if(wsaData.wVersion!=version)
{
printf("不支持WIDOWS的套接字\n");
getchar();
return ;
}
bool flag=true;
while(flag)
{
printf("Ping>:");
scanf("%s",pstrHost);
if(strcmp(pstrHost,"exit")==0)
break;
printf("*****************************\n");
Ping(pstrHost);
}
WSACleanup();
}
void Ping(LPCSTR pstrHost)
{
SOCKET rawSocket;
LPHOSTENT lpHost;
struct sockaddr_in saDest;
struct sockaddr_in saSrc;
DWORD dwTimeSent;
DWORD dwElapsed;
u_char cTTL;
int nLoop;
int nRet;
rawSocket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
if(rawSocket==SOCKET_ERROR)
{
ReportError("套接字");
return;
}
lpHost=gethostbyname(pstrHost);
if(lpHost==NULL)
{
printf("无法找到这主机[%s]\n",pstrHost);
getchar();
return;
}
saDest.sin_addr.s_addr=*((u_long FAR*)(lpHost->h_addr));
saDest.sin_family=AF_INET;
saDest.sin_port=0;
printf("\n探测主机%s[%s]:%d字节\n",pstrHost,inet_ntoa(saDest.sin_addr),REQ_DATASIZE);
for(nLoop=0;nLoop<4;nLoop++)
{
SendEchoRequest(rawSocket,&saDest);
nRet=WaitForEchoReply(rawSocket);
if(nRet==SOCKET_ERROR)
{
ReportError("选择");
break;
}
if(!nRet)
{
printf("发送超时\n");
break;
}
dwTimeSent=RecvEchoReply(rawSocket,&saSrc,(char*)&cTTL);
dwElapsed=time-dwTimeSent;
printf("来自主机[%s]响应,字节:%d 时间:%ld毫秒 最大生存期:%d\n",inet_ntoa(saSrc.sin_addr),REQ_DATASIZE,dwElapsed,cTTL);
}
if(closesocket(rawSocket)==SOCKET_ERROR)
ReportError("关闭套接字");
}
int SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)
{
static ECHOREQUEST echoReq;
static nId=1;
static nSeq=1;
static nRet;
echoReq.icmpHdr.Type=ICMP_ECHOREQ;
echoReq.icmpHdr.Code=0;
echoReq.icmpHdr.Checksum=0;
echoReq.icmpHdr.ID=nId++;
echoReq.icmpHdr.Seq=nSeq++;
for(nRet=0;nRet
echoReq.cData[nRet]=nRet;
echoReq.dwTime=GetTickCount();
time=echoReq.dwTime;//记录发送时间
echoReq.icmpHdr.Checksum=in_cksum((u_short *)&echoReq,sizeof(ECHOREQUEST));
nRet=sendto(s,(LPCSTR)&echoReq,sizeof(ECHOREQUEST),0,(LPSOCKADDR)lpstToAddr,sizeof(SOCKADDR_IN));
if(nRet==SOCKET_ERROR)
ReportError("发送出错");
return nRet;
}
void ReportError(LPCSTR lpStr)
{
printf("%s发生错误,错误号:%d\n",lpStr,WSAGetLastError());
getchar();
}
DWORD RecvEchoReply(SOCKET s,LPSOCKADDR_IN lpsaFrom,char *pTTL)
{
ECHOREPLY echoReply;
int nRet;
int nAddrLen=sizeof(struct sockaddr_in);
nRet=recvfrom(s,(LPSTR)&echoReply,sizeof(ECHOREPLY),0,(LPSOCKADDR)lpsaFrom,&nAddrLen);
if(nRet==SOCKET_ERROR)
ReportError("接收");
*pTTL=echoReply.ipHdr.TTL;
return echoReply.echoRequest.dwTime;
}
int WaitForEchoReply(SOCKET s)
{
struct timeval Timeout;
fd_set readfds;
readfds.fd_count=1;
readfds.fd_array[0]=s;
Timeout.tv_sec=5;
Timeout.tv_usec=0;
return select(1,&readfds,NULL,NULL,&Timeout);
}
u_short in_cksum(u_short *addr,int len)
{
register int nleft=len;
register u_short *w=addr;
register u_short answer;
register int sum=0;
while(nleft>1)
{
sum+=*w++;
nleft-=2;
}
if(nleft==1)
{
u_short u=0;
*(u_char *)(&u)=*(u_char *)w;
sum+=u;
}
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
answer=~sum;
return answer;
}
基于VC++6.0直接编译即可。