1

这两行在 中产生以下输出gdb。注意两个临时字符串的地址,first_str并且second_str有相同的地址。这是为什么?

char *first_str = inet_ntoa(first->dest);
char *second_str = inet_ntoa(second->dest);


(gdb) p first_str
$3 = 0x7ffff7ff06d8 "54.208.71.98"
(gdb) p second_str
$4 = 0x7ffff7ff06d8 "54.208.71.98"

first->destsecond->dest包含不同的值。

4

2 回答 2

7

inet_ntoa 在其实现中使用静态缓冲区,因此基本上每个调用都将 ascii ip 地址写入同一个位置。见下文:

https://www.opensource.apple.com/source/Libc/Libc-167/net.subproj/inet_ntoa.c

char *
inet_ntoa(in)
    struct in_addr in;
{
    static char b[18];
    register char *p;

    p = (char *)∈
#define UC(b)   (((int)b)&0xff)
    (void)snprintf(b, sizeof(b),
        "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
    return (b);
}

您应该使用inet_ntop

inet_ntop 还具有支持 IPv6 的额外好处,任何新编写的代码都应该寻求支持。

inet_ntop 的用法:

char ip[INET_ADDRSTRLEN];
if (!inet_ntop(AF_INET, &addr.sin_addr, ip, sizeof(ip))) {
    /// do something with error
}
于 2013-09-30T05:38:41.003 回答
2

inet_ntoa 文档

“应用程序不应该对分配内存的方式做出任何假设。返回的字符串保证只有在下一次 Windows Sockets 函数调用在同一个线程中之前才有效。”

它似乎只使用了一个静态缓冲区。因此,您需要在下次调用之前将结果复制到新缓冲区。

于 2013-09-30T05:39:10.240 回答