您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 网络ping--源代码(注有详细注释)
/*头文件部分*/#includewinsock2.h//windows下socket通信所必须的函数库#includestdio.h//C语言标准库#includetime.h//导入系统滴答计时器函数,为计算报文传输时间#includestring.h//字符串处理函数库#includeping.h//用户自己的函数声明与数据结构体定义内容导入#pragmacomment(lib,ws2_32)#defineCMD_PARAM_HELPtrue#defineICMP_ECHO8#defineICMP_ECHOREPLY0#defineICMP_MIN8//最小8字节的头#defineMAX_PACKET1024//最大ICMP包长度#defineMAX_IP_HDR_SIZE60typedefstructiphdr{unsignedinth_len:4;//4位首部长度unsignedintversion:4;//IP版本号,4表示IPV4unsignedchartos;//8位服务类型TOSunsignedshorttotal_len;//16位总长度(字节)unsignedshortident;//16位标识unsignedshortfrag_and_flags;//3位标志位unsignedcharttl;//8位生存时间TTLunsignedcharproto;//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,%shost[data_size]\n,progname);fprintf(stderr,datasizecanbeupto1Kb\n);ExitProcess(STATUS_FAILED);}intmain(intargc,char**argv){//初始化套接字WSADATAwsaData;SOCKETsockRaw;structsockaddr_indest,from;structhostent*hp;intbread,datasize;//定义bread,datasizeintfromlen=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(argc2){//残数个数小于2,即执行Usage(argv[0]);//调用函数argv}sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,0);//创建数据库if(sockRaw==INVALID_SOCKET){//检查套接是否合法fprintf(stderr,WSASocket()failed:%d\n,WSAGetLastError());ExitProcess(STATUS_FAILED);//退出}bread=setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));//设置超时时间if(bread==SOCKET_ERROR)//检查设置选项是否失败{fprintf(stderr,failedtosetrecvtimeout:%d\n,WSAGetLastError());ExitProcess(STATUS_FAILED);}timeout=1000;//时间输出为1000memset(&dest,0,sizeof(dest));//给最大内存清零hp=gethostbyname(argv[1]);//函数调用if(!hp)//域名解析{addr=inet_addr(argv[1]);//得到域名的数值地址}if((!hp)&&(addr==INADDR_NONE))//域名储出错,比如不能获取、域名不对{fprintf(stderr,Unabletoresolve%s\n,argv[1]);//输出ExitProcess(STATUS_FAILED);//退出}if(hp!=NULL)//判断是否有IP地址memcpy(&(dest.sin_addr),hp-h_addr,hp-h_length);elsedest.sin_addr.s_addr=addr;//给目标地址if(hp)dest.sin_family=hp-h_addrtype;//目标地址赋值elsedest.sin_family=AF_INET;//目标地址赋值dest_ip=inet_ntoa(dest.sin_addr);//传送IP地址if(argc2){//判断argc是否大于2datasize=atoi(argv[2]);if(datasize==0)//判断datasizedatasize=DEF_PACKET_SIZE;//赋值}elsedatasize=DEF_PACKET_SIZE;datasize+=sizeof(IcmpHeader);icmp_data=(char*)malloc(MAX_PACKET);//调用最大内存char型强制转换recvbuf=(char*)malloc(MAX_PACKET);//调用最大内存char型强制转换if(!icmp_data){//检查指针是否有效fprintf(stderr,HeapAllocfailed%d\n,GetLastError());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();//时间戳((IcmpHeader*)icmp_data)-i_seq=seq_no++;//序列号((IcmpHeader*)icmp_data)-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){//判断失败的是不是WSAETIMEDOUTprintf(timedout\n);//输出timedout\ncontinue;//结束这个判断}fprintf(stderr,sendtofailed:%d\n,WSAGetLastError());//输出,WSAGetLastError()是获取错误的代码ExitProcess(STATUS_FAILED);}if(bwrotedatasize){//判断发送缓冲区的大小fprintf(stdout,Wrote%dbytes\n,bwrote);//输出大小}bread=recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(structsockaddr*)&from,&fromlen);//接送报文的大小if(bread==SOCKET_ERROR){//判断报文的是不是带有SOCKET_ERRORif(WSAGetLastError()==WSAETIMEDOUT){//判断WSAETIMEDOUTprintf(timedout\n);//输出timedout\ncontinue;//结束if}fprintf(stderr,recvfromfailed:%d\n,WSAGetLastError());//输出ExitProcess(STATUS_FAILED);//退出}decode_resp(recvbuf,bread,&from);//recvbuf为8位Sleep(1000);}return0;//返回}voiddecode_resp(char*buf,intbytes,structsockaddr_in*from){//定义报头及各个含义IpHeader*iphdr;//定义IP报头IcmpHeader*icmphdr;//定义ICMP报头unsignedshortiphdrlen;iphdr=(IpHeader*)buf;//IP首部的地址就等于buf的地址iphdrlen=iphdr-h_len*4;//因为h_len是32位word,要转换成bytes必须*if(bytesiphdrlen+ICMP_MIN){//判断iphdrlen+ICMP_MIN相加后的大小与bytesprintf(Toofewbytesfrom%s\n,inet_ntoa(from-sin_addr));//取出源地址}icmphdr=(IcmpHeader*)(buf+iphdrlen);//ICMP首部的地址等于IP首部长加bufif(icmphdr-i_type!=ICMP_ECHOREPLY){fprintf(stderr,non-echotype%drecvd\n,icmphdr-i_type);//设置接收超时return;//结束,返回}if(icmphdr-i_id!=(USHORT)GetCurrentProcessId()){fprintf(stderr,someonee
本文标题:网络ping--源代码(注有详细注释)
链接地址:https://www.777doc.com/doc-7249996 .html