getaddrinfo使用localhost返回2个结果

时间:2013-01-21 14:37:44

标签: c linux sockets networking getaddrinfo

我正在尝试将函数getaddrinfo与被动套接字/侦听器一起使用,而不是直接填充旧的sockaddr结构。 我的目的是打开一个套接字并将其绑定到一个端口。基本上我正在构建一个服务器。

我不知道为什么,getaddrinfo会返回2个结果;因为这个在第二次循环下面我调用绑定它退出时出现错误,说“地址已经在使用中”。 你知道如何解决这个问题吗?如果把它放在循环中是正确的吗?

         struct addrinfo addr;
         memset(&addr,0,sizeof(addrinfo));
         addr.ai_family   = AF_INET;
         addr.ai_socktype = SOCK_STREAM;
         addr.ai_protocol = 0;
         addr.ai_flags    = AI_PASSIVE;

         struct addrinfo * rp,* result;
         getaddrinfo( "localhost","59001",&addr,&result );
         for( rp = result; rp != NULL; rp = rp->ai_next ){

              int sd = socket( AF_INET, SOCK_STREAM, 0 );
              if(-1==sd ){ 
              printf( "error creating the socket %m");
              return -1; 
              }             

             if( -1==bind( sd, result->ai_addr, result->ai_addrlen ) ){                 
             printf( "error binding %m")
             return -1;
             }

             if( -1== listen(sd, MAX_BACKLOG ) ){
             std::cerr << "listen didn't work" << std::endl;
             return -1;
             }       
         }

2 个答案:

答案 0 :(得分:4)

这里有几件事情要发生。对于来自getaddrinfo()的多个结果,这是因为它返回IPv4地址和IPv6地址(两者都有)。至于“已使用的地址”,您需要设置SO_REUSEADDR选项。在您致电socket()bind()

之间进行此操作
int opval = 1;
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

答案 1 :(得分:0)

这是在redhat机器上的吗?有一个众所周知的错误,因为/etc/hosts/列出了localhost两次,当你专门请求AF_INET时,你实际上会得到两次相同的结果;一次用于IPv4,一次用于IPv6翻译。

另见https://bugzilla.redhat.com/show_bug.cgi?id=496300