网络ping源代码注有详细注释Word文档下载推荐.doc
《网络ping源代码注有详细注释Word文档下载推荐.doc》由会员分享,可在线阅读,更多相关《网络ping源代码注有详细注释Word文档下载推荐.doc(6页珍藏版)》请在冰豆网上搜索。
#defineMAX_IP_HDR_SIZE60
typedefstructiphdr{
unsignedinth_len:
4;
//4位首部长度
unsignedintversion:
//IP版本号,4表示IPV4
unsignedchartos;
//8位服务类型TOS
unsignedshorttotal_len;
//16位总长度(字节)
unsignedshortident;
//16位标识
unsignedshortfrag_and_flags;
//3位标志位
unsignedcharttl;
//8位生存时间TTL
unsignedcharproto;
//8位协议(TCP,UDP或其他)
unsignedshortchecksum;
//16位IP首部校验和
unsignedintsourceIP;
//32位源IP地址
unsignedintdestIP;
//32位目的IP地址
}IpHeader;
//定义ICMP首位
/************************************************
//主程序入口
************************************************/
typedefstruct_ihdr{
BYTEi_type;
//8位类型
BYTEi_code;
//8位代码
USHORTi_cksum;
//16位校验和
USHORTi_id;
//识别号(一般用进程号作为识别号)
USHORTi_seq;
//报文序列号
ULONGtimestamp;
//时间戳
}IcmpHeader;
#defineSTATUS_FAILED0xFFFF
#defineDEF_PACKET_SIZE32//包的大小
#defineMAX_PACKET1024//最大ICMP包长度
#definexmalloc(s)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
#definexfree(p)HeapFree(GetProcessHeap(),0,(p))
voidfill_icmp_data(char*,int);
//填补数据
USHORTchecksum(USHORT*,int);
//校验数据
voiddecode_resp(char*,int,structsockaddr_in*);
voidUsage(char*progname){
fprintf(stderr,"
Usage:
\n"
);
//传送格式化数据
fprintf(stderr,"
%s<
host>
[data_size]\n"
progname);
datasizecanbeupto1Kb\n"
ExitProcess(STATUS_FAILED);
}
intmain(intargc,char**argv){//初始化套接字
WSADATAwsaData;
SOCKETsockRaw;
structsockaddr_indest,from;
structhostent*hp;
intbread,datasize;
//定义bread,datasize
intfromlen=sizeof(from);
inttimeout=1000;
//等待每次回复的超时时间,默认1秒
char*dest_ip;
//发送IP地址
char*icmp_data;
char*recvbuf;
unsignedintaddr=0;
//初始化地址
USHORTseq_no=0;
//序列号初始化
if(WSAStartup(MAKEWORD(2,1),&
wsaData)!
=0){//初始化函数
fprintf(stderr,"
WSAStartupfailed:
%d\n"
GetLastError());
//设置显示
ExitProcess(STATUS_FAILED);
//退出
}
if(argc<
2){//残数个数小于2,即执行
Usage(argv[0]);
//调用函数argv
sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,0);
//创建数据库
if(sockRaw==INVALID_SOCKET){//检查套接是否合法
WSASocket()failed:
WSAGetLastError());
//退出
bread=setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&
timeout,sizeof(timeout));
//设置超时时间
if(bread==SOCKET_ERROR)//检查设置选项是否失败
{
failedtosetrecvtimeout:
timeout=1000;
//时间输出为1000
memset(&
dest,0,sizeof(dest));
//给最大内存清零
hp=gethostbyname(argv[1]);
//函数调用
if(!
hp)//域名解析
addr=inet_addr(argv[1]);
//得到域名的数值地址
if((!
hp)&
&
(addr==INADDR_NONE))//域名储出错,比如不能获取、域名不对
{
Unabletoresolve%s\n"
argv[1]);
//输出
//退出
}
if(hp!
=NULL)//判断是否有IP地址
memcpy(&
(dest.sin_addr),hp->
h_addr,hp->
h_length);
else
dest.sin_addr.s_addr=addr;
//给目标地址
if(hp)
dest.sin_family=hp->
h_addrtype;
//目标地址赋值
dest.sin_family=AF_INET;
//目标地址赋值
dest_ip=inet_ntoa(dest.sin_addr);
//传送IP地址
if(argc>
2){//判断argc是否大于2
datasize=atoi(argv[2]);
if(datasize==0)//判断datasize
datasize=DEF_PACKET_SIZE;
//赋值
datasize=DEF_PACKET_SIZE;
datasize+=sizeof(IcmpHeader);
icmp_data=(char*)malloc(MAX_PACKET);
//调用最大内存char型强制转换
recvbuf=(char*)malloc(MAX_PACKET);
if(!
icmp_data){//检查指针是否有效
HeapAllocfailed%d\n"
ExitProcess(STATUS_FAILED);
}
memset(icmp_data,0,MAX_PACKET);
fill_icmp_data(icmp_data,datasize);
while
(1){//ICMP打包
intbwrote;
//定义bwrote
((IcmpHeader*)icmp_data)->
i_cksum=0;
//校验盒
((IcmpHeader*)icmp_data)->
timestamp=GetTickCount();
//时间戳
i_seq=seq_no++;
//序列号
i_cksum=checksum((USHORT*)icmp_data,datasize);
//校验盒
bwrote=sendto(sockRaw,icmp_data,datasize,0,(structsockaddr*)&
dest,sizeof(dest));
//发送
if(bwrote==SOCKET_ERROR){//判断发送是不是失败了
if(WSAGetLastError()==WSAETIMEDOUT){//判断失败的是不是WSAETIMEDOUT
printf("
timedout\n"
//输出timedout\n
continue