【问题标题】:getaddrinfo() returns loopback addressgetaddrinfo() 返回环回地址
【发布时间】:2013-11-26 08:33:29
【问题描述】:

我在 LAN 中用于某些套接字通信应用程序的目标机器具有用于 IPv4 的 192.168.98.91

当我尝试使用 getaddrinfo() 解析 IP 地址时,它返回 127.0.0.1

我怎样才能得到192.168.98.91

我在/etc/hostsfile 中为myhost 设置了192.168.98.91,我对myhost 执行的ping 操作将192.168.98.91 显示为IP 地址。

我的机器是CentOS6.4。

这是 /etc/hosts 的设置。

192.168.98.91   myhost
127.0.0.1   myhost localhost.localdomain 

这是我的代码。

#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>
#include <arpa/inet.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);
    //n = sendto(sock,"HELLO", 5, 0,(struct sockaddr *)addr, sizeof(addr));
    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;
}

【问题讨论】:

  • 显示getaddrinfo() 实际使用方式的代码似乎对于理解它的问题至关重要。敢给我们看……! ;-)
  • 你走过getaddrinfo返回的地址链表吗?
  • 你浏览过列表了吗? getaddrinfo() 可能会给你多个地址。
  • 所描述的症状听起来很奇怪,因为只有在请求localhostlo 或类似的情况下才会弹出回送地址。所以我建议你也给我们看看机器的/etc/hosts/etc/hosts.conf文件。
  • 我编辑添加了我的代码和主机设置。我不使用 hosts.conf。

标签: c sockets


【解决方案1】:

如果您使用struct addrinfoai_next 成员跟踪getaddrinfo() 返回的结果链,您还将获得192.168.98.91myhost

在这里http://man7.org/linux/man-pages/man3/getaddrinfo.3.html 你可以找到一个完整的例子,也展示了如何做到这一点:

从上面的链接:

       ...
       s = getaddrinfo(NULL, argv[1], &hints, &result);
       if (s != 0) {
           fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
           exit(EXIT_FAILURE);
       }

       /* getaddrinfo() returns a list of address structures.
          Try each address until we successfully bind(2).
          If socket(2) (or bind(2)) fails, we (close the socket
          and) try the next address. */

       for (rp = result; rp != NULL; rp = rp->ai_next) {
          /* Do something with rp->ai_family, rp->ai_socktype, ... */
       }
       ...

/etc/hosts 的这一行中删除myhost

127.0.0.1   myhost localhost.localdomain 

将导致127.0.0.1 在请求myhost 时不再被getaddrinfo() 返回。

【讨论】:

  • 现在我可以看到192.168.98.91
猜你喜欢
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 1970-01-01
相关资源
最近更新 更多