端口复用最常用的用途应该是防止服务器重启时之前绑定的端口还未释放或者程序突然退出而系统没有释放端口。此时如果设定了端口复用,
则新启动的服务器进程可以直接绑定端口。如果没有设定端口复用,绑定会失败,提示ADDR已经在使用中——那只好等等再重试了。
在TCP断开链接时需要四次握手来断开,当两端都关闭了read/write通道以后还是要等待一个TIME_WAIT时间(作用是在网络中残余的TCP包消失)。
一般来说,一个端口释放后会等待两分钟之后或三十秒才能再被使用,SO_REUSEADDR是让端口释放后立即就可以被再次使用。
SO_REUSEADDR套接字选项通知内核,如果TCP状态位于 TIME_WAIT ,可以重用端口。如果TCP状态位于其他状态,重用端口时依旧得到一个错误信息,指明"地址已经使用中"。如果你的服务程序停止后想立即重启,而新套接字依旧使用同一端口,此时SO_REUSEADDR 选项非常有用。必须意识到,此时任何非期望数据到达,都可能导致服务程序反应混乱,不过这种可能,事实上几率很小。
套接字由相关五元组构成,协议、本地地址、本地端口、远程地址、远程端口。SO_REUSEADDR 仅仅表示可以重用本地本地地址、本地端口,整个相关五元组还是唯一确定的。
应用方法:所有TCP服务器中,在调用bind之前设置SO_REUSEADDR套接口选项;
int bOptval=1;
int retSetsockopt=setsockopt(gServerListenSock,SOL_SOCKET ,SO_REUSEADDR ,(char *)&bOptval,sizeof(bOptval));
if (SOCKET_ERROR==retSetsockopt)
{
return 0;
}
端口复用允许在一个应用程序可以把 n 个套接字绑在一个端口上而不出错。同时,这 n 个套接字发送信息都正常,没有问题。
但是,这些套接字并不是所有都能读取信息,只有最后一个套接字会正常接收数据,这个特性都为后门程序所应用.
SO_EXCLUSIVEADDRUSE和SO_REUSEPORT作用相反,不允许使用 端口复用,但这个参数只存在于windows中。
注意:如果是服务器,新老socket都要加SO_REUSEADDR参数;要想同地址同端口绑定,只能用在udp的多播。