在网络应用中(如Java Socket Server),当服务关掉立马重启时,不少时候会提示端口仍被占用(因端口上有处于TIME_WAIT的链接)。此时可经过 SO_REUSEADDR 参数( socket.setReuseAddress(true); )来使得服务关掉重启时立马可以使用该端口,而不是提示端口占用。
若是端口忙,但TCP状态位于 TIME_WAIT ,能够重用 端口。若是端口忙,而TCP状态位于其余状态,重用端口时依旧获得一个错误信息, 抛出“Address already in use: JVM_Bind”。若是你的服务程序中止后想当即重启,不等60秒,而新套接字依旧 使用同一端口,此时 SO_REUSEADDR 选项很是有用。必须意识到,此时任何非期 望数据到达,均可能致使服务程序反应混乱,不过这只是一种可能,事实上很不可能。
在linux socket网络编程中,大规模并发TCP或UDP链接时,常常会用到端口复用:
int opt = 1;
if(setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR, (const void *) &opt, sizeof(opt))){
perror("setsockopt");
return -1;
}
在A机上进行客户端网络编程,假如它所使用的本地端口号是1234,若是没有开启端口复用的话,它用本地端口1234去链接B机再用本地端口链接C机时就不能够,若开启端口复用的话在用本地端口1234访问B机的状况下还能够用本地端口1234访问C机。如果服务器程序中监听的端口,即便开启了复用,也不能够用该端口望外发起链接了。
编写 TCP/SOCK_STREAM 服务程序时,SO_REUSEADDR到底什么意思?
A:这个套接字选项通知内核,若是端口忙,但TCP状态位于 TIME_WAIT ,能够重用端口。若是端口忙,
而TCP状态位于其余状态,重用端口时依旧获得一个错误信息,指明"地址已经使用中"。若是你的服务程序中止
后想当即重启,而新套接字依旧使用同一端口,此时SO_REUSEADDR 选项很是有用。必须意识到,此时任何
非指望数据到达,均可能致使服务程序反应混乱,不过这只是一种可能,事实上很不可能。
当两个socket的address和port相冲突,而你又想重用地址和端口,则旧的socket和新的socket都要已经被设置了SO_REUSEADDR特性,只有二者之一有这个特性仍是有问题的。
一、当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时,而你启动的程序的socket2要占用该地址和端口,你的程序就要用到该选项。
二、SO_REUSEADDR容许同一port上启动同一服务器的多个实例(多个进程)。但每一个实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器能够测试这种状况。
三、SO_REUSEADDR容许单个进程绑定相同的端口到多个socket上,但每一个socket绑定的ip地址不一样。这和2很类似,区别请看UNPv1。
四、SO_REUSEADDR容许彻底相同的地址和端口的重复绑定。但这只用于UDP的多播,不用于TCP