程序主要实现接收到主机ping命令后,在数据包中加入系统时间后返回给主机。定义了如下结构体:
typedef   struct   _IP{ 
union 
{   
BYTE   Version; 
BYTE   HdrLen; 
}; 
BYTE   ServiceType;
WORD   TotalLen; 
WORD   ID; 
union 
{   
WORD   Flags;  
WORD   FragOff; 
}; 
BYTE   TimeToLive; 
BYTE   Protocol; 
WORD   HdrChksum;
DWORD   SrcAddr;  
DWORD   DstAddr; 
BYTE   Options; 
}   IP;  接收ping代码为:while(TRUE) 

int ret = recv(sock, RecvBuf, size, 0);
               _IP   ip   =   *(IP*)RecvBuf;
DWORD addd = ip.SrcAddr;   //addd = 3825313984,对应IP=192.168.1.228
char* sa = inet_ntoa(*(in_addr*)&addd);
DWORD addd2 = ip.DstAddr;   //addd2 = 2634131648,对应IP=192.168.1.157
char* da = inet_ntoa(*(in_addr*)&addd2);
int len = ntohs(ip.TotalLen);
printf("from %s , to %s , recv size %d, pack size %d \n",sa, da, ret, len);
}但测试时发现ip.SrcAddr和ip.DstAddr是正确的,而sa 和da 都是192.168.1.157,请问这是为什么啊?为什么2个值一样呢?

解决方案 »

  1.   

     
    你的 inet_ntoa 使用了临时量
    为每个 地址 使用一个CopyMemory另外 这样定义似乎 不对
      union 
        {   
            BYTE   Version; 
            BYTE   HdrLen; 
        }; 
    应该是  
    #ifdef 小尾字序
    BYTE Version : 4;
    BYTE HdrLen :4;
    #else /*大尾字序*/
    BYTE HdrLen :4;
    BYTE Version : 4;
    #endif
      

  2.   

    请参考《WinSock网络编程经络》第11章,摘录书中内容如下:
    ================
    inet_ntoa把网络字节序的IP地址转换成点十进制的IP地址,符合人的阅读习惯。函数返回的字符串所用的内存是WinSock分配的,实际是在一个静态缓冲区中,也就意味着函数是不可重入的,WinSock只保证在同一线程中下一次的API调用之前该内存是有效的。如果应用程序要使用inet_ntoa的返回结果,需要自己分配内存,把结果保存下来。
    ================
    根据描述你的sa,da指向的是同一块静态缓冲区,所以值是最后一个的结果,即da的值,要想得到sa的,需要把数据拷贝到另外的缓冲区中.
      

  3.   

    好了,分开打印就ok了,
    printf("from %s ,",inet_ntoa(*(in_addr*)&ip.ipSource));
    printf("to %s ,", inet_ntoa(*(in_addr*)&ip.ipDestination));
    printf("pack size %d ,recv ticks %lld, last time %d us\n", ntohs(ip.ipLength), t1.QuadPart, cost);
    非常感谢楼上2位。。