一、通常来讲,一个端口释放后会等待两分钟以后才能再被使用,SO_REUSEADDR是让端口释放后当即就能够被再次使用。 html
SO_REUSEADDR用于对TCP套接字处于TIME_WAIT状态下的socket,才能够重复绑定使用。server程序老是应该在调用bind()以前设置SO_REUSEADDR套接字选项。TCP,先调用close()的一方会进入TIME_WAIT状态 服务器
二、SO_REUSEADDR和SO_REUSEPORT socket
SO_REUSEADDR提供以下四个功能: spa
SO_REUSEADDR容许启动一个监听服务器并捆绑其众所周知端口,即便之前创建的将此端口用作他们的本地端口的链接仍存在。这一般是重启监听服务器时出现,若不设置此选项,则bind时将出错。 .net
SO_REUSEADDR容许在同一端口上启动同一服务器的多个实例,只要每一个实例捆绑一个不一样的本地IP地址便可。对于TCP,咱们根本不可能启动捆绑相同IP地址和相同端口号的多个服务器。 server
SO_REUSEADDR容许单个进程捆绑同一端口到多个套接口上,只要每一个捆绑指定不一样的本地IP地址便可。这通常不用于TCP服务器。 htm
SO_REUSEADDR容许彻底重复的捆绑:当一个IP地址和端口绑定到某个套接口上时,还容许此IP地址和端口捆绑到另外一个套接口上。通常来讲,这个特性仅在支持多播的系统上才有,并且只对UDP套接口而言(TCP不支持多播)。 blog
SO_REUSEPORT选项有以下语义: 接口
此选项容许彻底重复捆绑,但仅在想捆绑相同IP地址和端口的套接口都指定了此套接口选项才行。 进程
若是被捆绑的IP地址是一个多播地址,则SO_REUSEADDR和SO_REUSEPORT等效。
使用这两个套接口选项的建议:
在全部TCP服务器中,在调用bind以前设置SO_REUSEADDR套接口选项;
当编写一个同一时刻在同一主机上可运行屡次的多播应用程序时,设置SO_REUSEADDR选项,并将本组的多播地址做为本地IP地址捆绑。
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
(const void *)&nOptval , sizeof(int)) < 0) ...
附
Q:编写 TCP/SOCK_STREAM 服务程序时,SO_REUSEADDR到底什么意思?
A:这个套接字选项通知内核,若是端口忙,但TCP状态位于 TIME_WAIT ,能够重用端口。若是端口忙,而TCP状态位于其余状态,重用端口时依旧获得一个错误信息,指明"地址已经使用中"。若是你的服务程序中止后想当即重启,而新套接字依旧使用同一端口,此时SO_REUSEADDR 选项很是有用。必须意识到,此时任何非指望数据到达,均可能致使服务程序反应混乱,不过这只是一种可能,事实上很不可能。
一个套接字由相关五元组构成,协议、本地地址、本地端口、远程地址、远程端口。SO_REUSEADDR 仅仅表示能够重用本地本地地址、本地端口,整个相关五元组仍是惟一肯定的。因此,重启后的服务程序有可能收到非指望数据。必须慎重使用 SO_REUSEADDR 选项。【2】
【1】 http://topic.csdn.net/u/20090103/16/a0414edb-b289-4c72-84da-39e155e8f4be.html
【2】
如下博客对这个问题进行了对答式的解答: