我做了一个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分了,全给了。

解决方案 »

  1.   

    肯定在你decode_IpIcmp函数中解码错误了,因为你收到的数据也有可能是另外一个进程的ICMP数据包,所以,在解码ICMP数据时,应该先判断该数据是否为本进程发送ping所返回的数据包。  判断很简单,因为你所发送的ICMP是自己填充的,可以把进程ID填充进去,收到数据时,就检验该填充字段是否为本进程的ID,如果是才认为是对本进程myping 的响应。
      

  2.   

    比如,ICMP的头部如下定义:typedef struct icmp_hdr { 
     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,如果正确,才才是真正的你要的。
      

  3.   

    int decode_reply(IPHeader* reply, int bytes, sockaddr_in* from) 
    {
        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;
        }
       .......
        //继续处理
     }
      

  4.   


    谢谢各位,用你们的方法确实可以把不同进程的PING分开,不过还有一个问题,
    就是超时的判断,
    int iRecvSize = recvfrom(sockfd, recv_buffer, 1024, 0, (struct sockaddr*)&from,  &fromlen);
            
    iRecvSize<0 就是超时,但由于其他PING进程的返回包的干扰,这个iRecvSize 不小于0 了,(因为他收到了其他的PING进程的返回包)       按前面的方法,在decode_reply()中发现不是自己的包就返回,难道要重新再  sendto( ) 一次吗,可如果其他PING进程不断地返回包怎么办。