我正在尝试将函数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;
}
}
答案 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翻译。