我有一个服务器实现,我需要2个独立的套接字 - 1个IPv4套接字套接字监听特定的IPv4地址和服务器端口X,以及IPv6套接字监听特定的IPv6地址和相同的服务器端口X. IPv4和IPv6地址在同一个界面上。
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(v4addr);
sin.sin_port = htons(tcp_port);
我正在使用evconnlistener_new_bind创建ipv4套接字并绑定到它。 对于IPv6侦听器,代码如下。
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
memcpy(sin6.sin6_addr.s6_addr, v6addr_bytes, IPV6_ADDR_LEN);
sin6.sin6_port = htons(tcp_port);
fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
evutil_make_socket_nonblocking(fd)
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&on, sizeof(on))
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&on, sizeof(on))
evutil_make_listen_socket_reuseable(fd) /* Libevent call to set SO_REUSEADDR */
evutil_make_socket_nonblocking(fd) /* Libevent call to set fd non-blocking */
bind(fd, (const struct sockaddr *)&sin6, sizeof(sin6))
当我将fd绑定到特定的ipv6地址时,我间歇性地看到绑定失败。
绑定v6失败sin6 3ffe :: a00:513 - 错误99 - 无法分配请求的地址
我尝试了gdb,但每次gdb进入时,绑定都会成功。
我不确定为什么我会看到这个问题。有人可以帮忙吗?
答案 0 :(得分:0)
默认情况下,在套接字绑定到TCP端口后,端口在套接字关闭时保留一分钟 - 这称为TCP TIME_WAIT
状态。 TIME_WAIT
避免了一些可能导致数据损坏的竞争条件,但忽略服务器端的TIME_WAIT
通常是安全的。
这可以通过设置SO_REUSEADDR
套接字选项来完成:
int one = 1;
rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))