2

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

我不知道为什么但getaddrinfo返回 2 个结果;因此,在第二次下面的循环中,我调用 bind 它退出时出现错误消息“地址已在使用中”。你知道如何解决这个问题,以及将它放在一个循环中是否正确?

         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;
             }       
         }
4

2 回答 2

4

这里发生了几件事。对于来自 的多个结果getaddrinfo(),这是因为它返回一个 IPv4 地址和一个 IPv6 地址(两者都有)。至于“地址已被使用”,则需要设置SO_REUSEADDR选项。socket()把它放在你对和的调用之间bind()

int opval = 1;
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
于 2013-01-21T14:54:32.647 回答
0

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

另请参阅https://bugzilla.redhat.com/show_bug.cgi?id=496300

于 2013-01-24T01:27:49.093 回答