实现tracert命令问题,WSAGetLastError()返回10060怎么解决啊?

CC第N次 2012-04-30 12:54:56
功能是实现tracert命令,但是 nRet=::recvfrom(。。。)返回的是-1,WSAGetLastError()==WSAETIMEDOUT,,是超时,实在是不知道怎么解决啊。。。。。。。代码如下:

#include "iostream.h"
#include "winsock2.h"
#include "ws2tcpip.h"
#include "sys/types.h"



#pragma comment(lib,"ws2_32")
//#define ICMP_PACK_SIZE (sizeof(ICMP_HEADER)+32)


//ICMP报头
typedef struct _ICMP_HEADER{
unsigned char icmp_type;
unsigned char icmp_code;
unsigned short icmp_checksum;

unsigned short icmp_id;
unsigned short icmp_sequence;
unsigned long icmp_timestamp;
}ICMP_HEADER,*PICMP_HEADER;


//IP报头
typedef struct _IP_HEADER{

unsigned char ip_version; //版本
unsigned char ip_tos; //区分服务
unsigned short ip_totallen;
unsigned short ip_id;
unsigned short ip_flags; //标志,最低位为MF,MF=1即表示后面“还有分片”
unsigned char ip_ttl; //生存时间
unsigned char ip_proto;
unsigned short ip_checksum; //只检验数据报首部
unsigned long ip_source;
unsigned long ip_destination;
}IP_HEADER,*PIP_HEADER;


int Tracert(char *lpDestIp)
{
//初始化WinSock库
WORD wVersionRequested=MAKEWORD(2,2); //指定载入动态库的版本
WSADATA wsaData;
if(WSAStartup(wVersionRequested,&wsaData)!=0) return false;


char recvBuf[1024]={0};

SOCKET sRaw=::socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
SOCKADDR_IN in; // SOCKADDR_IN指明地址信息的数据结构
in.sin_family=AF_INET;
in.sin_port=0;
in.sin_addr.S_un.S_addr=INADDR_ANY; //任意地址
if(::bind(sRaw,(sockaddr*)&in,sizeof(in))==SOCKET_ERROR)
{
cout<<"bind failed!"<<endl;
return false; //-----------------------------------------------------------
}

//SetTimeout(sRaw,5*1000);//----------------------------------------------
int time=5000;

int ret=::setsockopt(sRaw,SOL_SOCKET,SO_RCVTIMEO ,(char*)&time,sizeof(time)); //接收时限

if(ret==SOCKET_ERROR)
{
cout<<"sRaw set SO_RCVTIMEO error!"<<endl;
}



SOCKET sSend=::socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN destAddr;
destAddr.sin_family=AF_INET;
destAddr.sin_port=::htons(22);
destAddr.sin_addr.S_un.S_addr=::inet_addr(lpDestIp);

int nTTL=1;
int nRet;
ICMP_HEADER*pICMPHdr;
int nTick;

SOCKADDR_IN recvAddr; //反馈消息的来源地址
do{
//SetTTL(sSend,nTTL);//---------------------------------------------------

ret=::setsockopt(sSend, IPPROTO_IP,IP_TTL, (char*)&nTTL, sizeof(nTTL));
if(ret==SOCKET_ERROR)
{
cout<<"TTL set error!";
break;
}

nTick=::GetTickCount();
nRet=::sendto(sSend,"hello",5,0,(sockaddr*)&destAddr,sizeof(destAddr));

if(nRet==SOCKET_ERROR)
{
cout<<"sendto failed!"<<endl;
break;
}



int nLen=sizeof(recvAddr);
nRet=::recvfrom(sRaw,recvBuf,1024,0,(sockaddr*)&recvAddr,&nLen);


cout<<"nRet="<<nRet<<endl;
if(nRet==SOCKET_ERROR)
{
if(::WSAGetLastError()==WSAETIMEDOUT)
{
cout<<"WSAGetLastError()"<<WSAGetLastError()<<endl; //-----这里报错-----------
cout<<"sRaw recvfrom time out!"<<endl;
break;
//continue;
}
else {
cout<<"recvfrom failed!"<<endl;
break;
}
}
pICMPHdr=(ICMP_HEADER*)&recvBuf[sizeof(IP_HEADER)];

if(pICMPHdr->icmp_type!=11&&pICMPHdr->icmp_type!=0&&pICMPHdr->icmp_code!=0)
{
cout<<"Unexpected Type:"<<pICMPHdr->icmp_type<<endl;
cout<<"Unexpected Code:"<<pICMPHdr->icmp_code<<endl;
}


char *szIP=::inet_ntoa(recvAddr.sin_addr);
cout<<"第 "<<nTTL<<" 个路由器,IP地址为:"<<szIP<<endl;
cout<<"用时"<<GetTickCount()-nTick<<" ms"<<endl;

if(pICMPHdr->icmp_type==0&&pICMPHdr->icmp_code==0)
{
char *sz=&((char*)pICMPHdr)[sizeof(ICMP_HEADER)];
sz[nRet]='\0';
cout<<"目标可达:"<<sz<<endl;
break;
}
cout<<"----------------------------------------"<<endl;

}while(nTTL++<50);

::closesocket(sRaw);
::closesocket(sSend);
return true;
}



int main()
{
char lpDestIp[]="61.135.169.125";
Tracert(lpDestIp);
return 0;
}
...全文
930 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
CC第N次 2012-05-13
  • 打赏
  • 举报
回复
原来是没关防火墙。。。。。。。
CC第N次 2012-04-30
  • 打赏
  • 举报
回复
感谢回复,但是我还是想知道字节写的哪里出了问题?
Kaile 2012-04-30
  • 打赏
  • 举报
回复
vc实现tracert程序
http://wenku.baidu.com/view/eecb9060ddccda38376bafec.html

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧