【问题标题】:How to print IP address from getaddrinfo()如何从 getaddrinfo() 打印 IP 地址
【发布时间】:2013-11-21 07:54:40
【问题描述】:

我正在 CentOS 6.4 上尝试在 C 中使用套接字。

LIST1 之后是我的代码。

我的代码从命令行获取主机名,并成功通过 UDP 向服务器发送数据报。

我想知道的是如何打印getaddrinfo()解析为192.168.10.1格式的IP地址。

当我尝试打印 IP 地址分段错误时发生。

有人知道如何修复此代码吗?

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>

int
main(int argc,char *argv[]){
    int sock;
    struct addrinfo hints,*res;
    int n;
    int err;
    if(argc != 2){
        fprintf(stderr,"Usage : %s dst \n",argv[0]);
        return 1;
    } 
    memset(&hints,0,sizeof(hints));
    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_DGRAM;
    err = getaddrinfo(argv[1],"12345",&hints,&res);
    if(err != 0){
        perror("getaddrinfo");
        printf("getaddrinfo %s\n",strerror(errno));
        printf("getaddrinfo : %s \n",gai_strerror(err));
        return 1;
    }

    sock = socket(res->ai_family,res->ai_socktype,0);
    if(sock < 0){
        perror("socket");
        return 1;

        const char *ipverstr;
        switch (res->ai_family){
            case AF_INET:
                ipverstr = "IPv4";
                break;
            case AF_INET6:
                ipverstr = "IPv6";
                break;
            default:
                ipverstr = "unknown";
                break;            
        }
        printf("ipverstr = %s\n ",ipverstr);            
    }
    n = sendto(sock,"HELLO",5,0,res->ai_addr,res->ai_addrlen);
    if(n<1){
        perror("sendto");
        return 1;
    }
    struct sockaddr_in *addr;
    addr = (struct sockaddr_in *)res->ai_addr; 
    printf("inet_ntoa(in_addr)sin = %s\n",inet_ntoa((struct in_addr)addr->sin_addr));

    printf("############ finish !! #######\n");
    close(sock);
    freeaddrinfo(res);
    return 0;
}

【问题讨论】:

    标签: c sockets


    【解决方案1】:

    代码未包含inet_ntoa() 的原型。

    编译器应该已经告诉你了。

    添加:

    #include <arpa/inet.h>
    

    但是,由于缺少inet_ntoa() 的原型,代码仍然可以编译,它假定返回int,而它返回一个char*,它是一个指针,在 64 位系统上是 8 个字节,即与int 的大小不同,后者的大小通常为4。由于这种不匹配,事情会发生严重错误并最终导致分段违规。


    另外请注意:inet_ntoa() 仅用于 ipv4 地址。逐字逐句来自man inet_ntoa(我的斜体):

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


    为了能够将(IPv4 和 IPv6)struct sockaddr_XYZ 的二进制地址转换为 char[],请使用 inet_ntop()

    【讨论】:

    • 我添加了它并获得了IP地址。
    【解决方案2】:

    getaddrinfo() 的对应物是getnameinfo()。这会将struct sockaddr 转换为字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      • 2018-07-04
      • 1970-01-01
      • 2014-05-25
      • 1970-01-01
      • 1970-01-01
      • 2016-11-30
      相关资源
      最近更新 更多