我已经使用
SO_REUSEADDR
让我的服务器终止并重新启动,而不会抱怨套接字已在使用中。我想知道:SO_REUSEADDR
还有其他用途吗?除了上述目的之外,还有人使用套接字选项吗?
对于 TCP,主要目的是在同一地址上重新启动已关闭/终止的进程。
需要该标志,因为端口进入
TIME_WAIT
状态以确保传输所有数据。
如果两个套接字绑定到相同的接口和端口,并且它们是同一多播组的成员,则数据将传递到两个套接字。
我猜另一种用途是尝试拦截数据的安全攻击。
(来源)
对于 UDP,
SO_REUSEADDR
用于多播。
如果
前面有:SOCK_DGRAM
,则多个进程可能绑定到同一个bind()
UDP 端口int one = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
在这种情况下,每个传入的多播或广播 UDP 数据报都注定 共享端口被传递到绑定到该端口的所有套接字。
(来源)
另一个主要用途是允许多个套接字
bind()
连接到 UDP 上的同一端口。您可能不会想到会出现这种情况,但有时多个应用程序可能想要侦听具有给定端口号的广播/多播地址。它还允许绑定到通配符地址,同时也绑定到特定地址。例如,Apache 可能绑定到 *:80 和 10.11.12.13:80
有关 TCP 的答案,请参阅@brian-r-bondy 的答案。但对于 UDP
const int enable = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) == -1) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
可以产生不同的效果:
[0:http://www.kohala.com/start/mcast.api.txt]
[1:http://ossasepia.com/2021/12/14/the-half-life-of-udp-sockets-or-reuseaddr/]