tracert 网络新手,有几个地方出问题了。
#include <Winsock2.h>#include <ws2tcpip.h> //进行IPPROTO_IP级别设置时用到#include <stdio.h>#include <stdlib.h>#include <string.h>#pragma comment(lib,"ws2_32.lib")//ICMP类型字段:#define ICMP_ECHO 8 //发送Ping请求时的ICMP报文类型#define ICMP_ECHOREPLY 0 //接收Ping回复时的ICMP报文类型#define ICMP_TIMEOUT 11 //ICMP超时报文类型#define ICMP_MIN 8 //Minimum 8-byte ICMP packet(header)#define MAX_PACKET 1024 //Max ICMP packet size#define DEICMP_PACKSIZE 44 //Defaut ICMP PACKET SIZE//ICMP头部定义typedef struct{ BYTE i_type; //报文类型 BYTE i_code; //代码 USHORT i_cksum; //校验和 USHORT i_id; //标识符 USHORT i_seq; //序号} IcmpHeader;int main(int argc,char **argv){ int i,ip_head_len,error; DWORD tick,starttick; struct sockaddr_in server,router; int routerlen=sizeof(router); IcmpHeader *icmp_hdr; SOCKET sockRaw; int timeout=1000; struct hostent *hp=NULL; //发送缓存 //char IcmpSendbuffer[sizeof(IcmpHeader) + DEICMP_PACKSIZE]={'\0'}; char IcmpSendbuffer[DEICMP_PACKSIZE]={'\0'}; //接收缓存 char IcmpRecvbuffer[MAX_PACKET]={'\0'}; //启动socket WSADATA wsaData; if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) { printf("WSAStartup() failed:%d\n",GetLastError()); return -1; } argv[1]="202.114.18.190";//////////////?????????????????????????????? //构造目的端的socket地址 server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr(argv[1]); //初始化icmp头部 icmp_hdr=(IcmpHeader *) IcmpSendbuffer; icmp_hdr->i_type=ICMP_ECHO;//request an ICMP echo icmp_hdr->i_code=0; icmp_hdr->i_id=(USHORT)GetCurrentProcessId(); icmp_hdr->i_cksum=0; icmp_hdr->i_seq=0; memset(IcmpSendbuffer+sizeof(IcmpHeader),'E',DEICMP_PACKSIZE-sizeof(IcmpHeader)); //创建套接字 sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED); if(sockRaw==INVALID_SOCKET) { printf("WSASocket() failed: %d\n",WSAGetLastError()); return -1; } //设置发送超时 error=setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout)); if(error==SOCKET_ERROR) { printf("setsockopt(SO_RCVTIMEO) failed:%d\n",WSAGetLastError()); return -1; } //设置接收超时 error=setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout)); if(error==SOCKET_ERROR) { printf("setsockopt(SO_SNDTIMEO) failed:%d\n",WSAGetLastError()); return -1; } //主机名解析 if(server.sin_addr.s_addr==INADDR_NONE) { if((hp=gethostbyname(argv[1]))==NULL) { printf("gethostbyname() failed: %d\n",WSAGetLastError()); return -1; } else { memcpy(&(server.sin_addr.s_addr),hp->h_addr_list[0],hp->h_length); server.sin_family=hp->h_addrtype; } } printf("\nTracing route to %s over a maximum of 30 hops\n\n",argv[1]); //发送/接收icmp报文 for(i=1;i<=30;i++) { //设置ip包的生存时间 setsockopt(sockRaw,IPPROTO_IP,IP_TTL,(char *)&i,sizeof(int)); //发送icmp报文 starttick=GetTickCount(); sendto(sockRaw,IcmpSendbuffer,DEICMP_PACKSIZE,0,(struct sockaddr *)&server,sizeof(server)); if(error==SOCKET_ERROR) { printf("sendto() failed:%d\n",WSAGetLastError()); return -1; } //接收icmp报文 recvfrom(sockRaw,IcmpRecvbuffer,MAX_PACKET,0,(struct sockaddr *)&router,&routerlen); tick=GetTickCount(); if(error==SOCKET_ERROR) { if(WSAGetLastError()==WSAETIMEDOUT ) { printf("%-2d * . * . * . * Request timed out.\n",i); continue; } else { printf("recvfrom() failed:%d\n",WSAGetLastError()); return -1; } } //对接收到的icmp差错报文进行分析 ip_head_len=(IcmpRecvbuffer[0]&0x0f)*4; icmp_hdr=(IcmpHeader*)(IcmpRecvbuffer+ip_head_len); //判断接收的是否为icmp超时报文 if(icmp_hdr->i_type==ICMP_TIMEOUT&&icmp_hdr->i_code==0) { printf("%-2d %-15s %4d ms\n",i, inet_ntoa(router.sin_addr),tick-starttick); } //判断接收的ICMP报文是否为回复报文 else if(icmp_hdr->i_type==ICMP_ECHOREPLY&&icmp_hdr->i_id==GetCurrentProcessId()) { printf("%-2d %-15s %4d ms\n",i, inet_ntoa(router.sin_addr),tick-starttick); printf("\nTrace complete!\n"); return 0; } else { printf("%2d: Destination host is unreachable!\n",i); } Sleep(1000); } return 0;}