9.2 SO_REUSEADDR
9.2 SO_REUSEADDR
该选项的作用:“Allow reuse of local addresses"
发生地址分配错误
服务器通过 ctrl + c 关闭程序,然后立即再次启动服务器,程序会报错。
执行情况:
ming@ubuntu:/media/sf_share/Network/build$ ./Network 192.168.56.101 10086
^C
ming@ubuntu:/media/sf_share/Network/build$ ./Network 192.168.56.101 10086
bind() error: Address already in use错误信息显示 Address already in use
Time-wait 状态
正常情况下,发起断开连接(先发送FIN的)的主机A,在发送完对主机B的 FIN 的 ACK 后会进入Time-wait 状态。这个状态是为了确保主机B收到了 FIN 的 ACK 响应,如果在计时段内 A 再次收到 B的FIN 说明 B 未收到 ACK,A 重新发送 ACK,并重置计时器。断开发起方A在计时器条件满足后消除socket。
如果关闭服务器后立即再次启动服务器,尝试绑定之前的端口。由于存在Time-wait 状态,此时前面的socket 还没有消除,端口被占用,所以无法绑定socket。
注
发起断开连接的socket 存在 Time-wait 状态。如果由客户端发起断开连接,客户端socket 也会存在 Time-wait 状态,只不过客户端socket 的端口通常是随机分配,再次连接服务器时 使用另外的端口,所以没有影响。
地址再分配
相关信息
调整 SO_REUSEADDR 参数,可将 Time-wait 状态下的套接字端口号重新分配给新的套接字.
SO_REUSEADDR 的默认值为0
问:重新分配后创建新的socket C,那么原来的socket - A 如何?是不存在 Time-wait 了,还是Time-wait 的职责被 C 继承了?又或者系统记录了状态,不影响原有的socket,Time-wait 功能正常(B的FIN 仍会发送给A),系统会清理 A?
参考AI:
相关信息
SO_REUSEADDR 允许你重新 bind 端口,但原来的 TIME-WAIT 连接仍然是独立存在的 TCP 控制块,继续完成 TIME-WAIT 的全部职责,直到内核自动清除。
实现:
int option = true;
socklen_t optlen = sizeof(option);
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&option, optlen);效果:
ming@ubuntu:/media/sf_share/Network/build$ ./Network 192.168.56.101 10086
^C
ming@ubuntu:/media/sf_share/Network/build$ ./Network 192.168.56.101 10086可以直接绑定