inet_ntoa发生了什么? [重复]

问题描述 投票:0回答:1

这个问题在这里已有答案:

让我感到困惑,这是一个不同结果的例子。这对我来说有点不对劲。

#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>


int main(){
    struct sockaddr_in src;
    struct sockaddr_in dest;

    memset(&src, 0, sizeof(src));
    src.sin_addr.s_addr = 0xEBAE277D;

    memset(&dest, 0, sizeof(dest));
    dest.sin_addr.s_addr = 0x6700A8C0;

    printf("saddr:%s\n", inet_ntoa(src.sin_addr));
    printf("daddr:%s\n", inet_ntoa(dest.sin_addr));
    printf("src:%15s------->dest:%15s\n", inet_ntoa(src.sin_addr), inet_ntoa(dest.sin_addr));
}

结果:

saddr:125.39.174.235
daddr:192.168.0.103
src: 125.39.174.235------->dest: 125.39.174.235
c sockets
1个回答
1
投票

inet_ntoa的文档说:

inet_ntoa()函数将以网络字节顺序给出的Internet主机地址转换为IPv4点分十进制表示法中的字符串。该字符串在静态分配的缓冲区中返回,后续调用将覆盖该缓冲区。

(这是来自Linux手册页;其他人有不同的措辞,但有关静态缓冲区的警告应该在某处)

所以你调用inet_ntoa一次,填充缓冲区,并返回指向它的指针。你再次调用它,缓冲区被覆盖,并再次返回指向它的指针。你把这两个指针传递给了printf,它打印了两次缓冲区内容。

要正确执行此操作,您需要将第一个inet_ntoa结果复制到您自己的本地缓冲区中,然后再次调用它,或者只使用2个printfs。

或者您可以使用inet_ntop,这需要您自己提供输出缓冲区。 (调用者提供的输出缓冲区在较新的接口中更常见;静态输出缓冲区起初看起来很容易,但从长远来看会导致类似代码中的事故。)

© www.soinside.com 2019 - 2024. All rights reserved.