windows下64位应用程序连续调用inet_ntoa解析源地址和目标地址,发现打印两个地址相同。调试了一下发现,inet_ntoa在64位下有问题。错误代码如下:
struct in_addr inAddrSrc;
struct in_addr inAddrDst;
inAddrSrc.s_addr = p_ip_hdr->ip_srcaddr;
inAddrDst.s_addr = p_ip_hdr->ip_destaddr;
char* pIpSrc = inet_ntoa(inAddrSrc);
char* pIpDst = inet_ntoa(inAddrDst);
printf("%s->%s\n", pIpSrc, pIpDst);
打印结果:192.168.1.40->192.168.1.40
解决方案可以有两种,如下:
1.使用时转换完毕就立即转给局部缓冲区变量
struct in_addr inAddrSrc;
struct in_addr inAddrDst;
char ipSrc[16];
char ipDst[16];
inAddrSrc.s_addr = p_ip_hdr->ip_srcaddr;
inAddrDst.s_addr = p_ip_hdr->ip_destaddr;
char* pIpSrc = inet_ntoa(inAddrSrc);
strcpy(ipSrc, pIpSrc);
char* pIpDst = inet_ntoa(inAddrDst);
strcpy(ipDst, pIpDst);
printf("%s->%s\n", ipSrc, ipDst);
2.重载inet_ntoa的实现
因为系统(Windows/Linux)提供的inet_ntoa()实现内部使用了一个static全局静态变量,故而连续调用会最后调用的数据会覆盖之前的。
char* inet_ntoa(char* addr, int size, struct in_addr in)
{
if (size >= 16)
{
sprintf(addr, ("%d.%d.%d.%d"), ((uint8_t*)&in.s_addr)[0], ((uint8_t*)&in.s_addr)[1], ((uint8_t*)&in.s_addr)[2], ((uint8_t*)&in.s_addr)[3]);
}
return addr;
}