我做了一个PING的程序myping,关键地方在下面。
int iSendSize = sendto(sockfd, buffer, sizeof(XIcmpHeader) + iIcmpDataSize, 0, (struct sockaddr*)&dest, sizeof(dest)); memset(&from, 0, sizeof from);
memset(recv_buffer, 0, 1024);
#ifdef WIN32
int fromlen = sizeof(from);
int iRecvSize = recvfrom(sockfd, recv_buffer, 1024, 0, (struct sockaddr*)&from, &fromlen);
#else
socklen_t fromlen = sizeof(from);
int iRecvSize = recvfrom(sockfd, recv_buffer, 1024, 0, (struct sockaddr*)&from, &fromlen);
#endif
if (iRecvSize > 0) decode_IpIcmp(recv_buffer, iRecvSize);
else {
return _T("超时" ) ; }
运行这个程序去ping 一个不通的IP,结果是正确的,它返回超时,但如果先运行这个
程序myping 不通的IP,再用WIN系统带的PING 来PING 127。0。0。1,则myping也显示收到返回
数据了,我分析返回的数据包,里面的发送地址是127。0。0。1,也就是说myping收到的
其实是系统ping 127.0.0.1 返回的包。
但如果用WIN系统带的PING 来PING -t 127。0。0。1,再用WIN系统带
的PING 来PING -t 不通的IP,它们彼此间不会发生干扰,PING -t 127。0。0。1
正常返回,PING -t 不通的IP 还是不通。
不知如何解决这个问题,我只有40分了,全给了。
int iSendSize = sendto(sockfd, buffer, sizeof(XIcmpHeader) + iIcmpDataSize, 0, (struct sockaddr*)&dest, sizeof(dest)); memset(&from, 0, sizeof from);
memset(recv_buffer, 0, 1024);
#ifdef WIN32
int fromlen = sizeof(from);
int iRecvSize = recvfrom(sockfd, recv_buffer, 1024, 0, (struct sockaddr*)&from, &fromlen);
#else
socklen_t fromlen = sizeof(from);
int iRecvSize = recvfrom(sockfd, recv_buffer, 1024, 0, (struct sockaddr*)&from, &fromlen);
#endif
if (iRecvSize > 0) decode_IpIcmp(recv_buffer, iRecvSize);
else {
return _T("超时" ) ; }
运行这个程序去ping 一个不通的IP,结果是正确的,它返回超时,但如果先运行这个
程序myping 不通的IP,再用WIN系统带的PING 来PING 127。0。0。1,则myping也显示收到返回
数据了,我分析返回的数据包,里面的发送地址是127。0。0。1,也就是说myping收到的
其实是系统ping 127.0.0.1 返回的包。
但如果用WIN系统带的PING 来PING -t 127。0。0。1,再用WIN系统带
的PING 来PING -t 不通的IP,它们彼此间不会发生干扰,PING -t 127。0。0。1
正常返回,PING -t 不通的IP 还是不通。
不知如何解决这个问题,我只有40分了,全给了。
u_char icmp_type; /* type of message */
u_char icmp_code; /* type sub code */
u_short icmp_cksum; /* ones complement cksum */
u_short icmp_id; /* 发送时,自己填充PID*/
u_short icmp_seq; /* sequence number */
char icmp_data[1]; /* data */
} ICMP_HDR, *PICMPHDR, FAR *LPICMPHDR; 收到数据后,可以先判断icmp_type,icmp_code,如果正确(注意发送的icmp_type和返回的是不一样的,一个==0,一个==8),再判断icmp_id,如果正确,才才是真正的你要的。
{
ICMP_HDR icmphdr
。。、//前面还有对包的处理
if (icmphdr->type != ICMP_ECHO_REPLY)//非正常回复
{
if (icmphdr->type != ICMP_TTL_EXPIRE) //ttl减为零
{
if (icmphdr->type == ICMP_DEST_UNREACH) { //主机不可达
cerr << "Destination unreachable" << endl;
}
else { //非法的ICMP包类型
cerr << "Unknown ICMP packet type " << int(icmphdr->type) <<
" received" << endl;
}
return -1;
}
}
else if (icmphdr->icmp_id!= (USHORT)GetCurrentProcessId())
{
//不是本进程发的包, 可能是同机的其它ping进程发的
return -2;
}
.......
//继续处理
}
谢谢各位,用你们的方法确实可以把不同进程的PING分开,不过还有一个问题,
就是超时的判断,
int iRecvSize = recvfrom(sockfd, recv_buffer, 1024, 0, (struct sockaddr*)&from, &fromlen);
iRecvSize<0 就是超时,但由于其他PING进程的返回包的干扰,这个iRecvSize 不小于0 了,(因为他收到了其他的PING进程的返回包) 按前面的方法,在decode_reply()中发现不是自己的包就返回,难道要重新再 sendto( ) 一次吗,可如果其他PING进程不断地返回包怎么办。