Ray*_*ton 57 sockets linux port ip-address setsockopt
从手册页:
SO_REUSEADDR指定在验证提供给bind()的地址时使用的规则应该允许重用本地地址(如果协议支持的话).此选项采用int值.这是一个布尔选项
我应该什么时候使用它?为什么"重用本地地址"给出了?
War*_*ung 129
TCP的主要设计目标是在数据包丢失,数据包重新排序和 - 密钥,这里 - 数据包复制时允许可靠的数据通信.
很明显TCP/IP网络堆栈如何在连接启动时处理所有这些,但是在连接关闭之后会出现边缘情况.如果在会话结束时发送的数据包被复制并延迟,以便4路关闭数据包在延迟数据包之前到达接收器会发生什么?堆栈尽职地关闭其连接.然后,延迟的重复数据包显示出来.堆栈应该做什么?
更重要的是,如果拥有该连接的程序立即死亡,那么它应该怎么办?那么另一个启动需要相同的IP地址和TCP端口号?
有几个选择:
禁止重用该IP /端口组合至少是数据包在飞行中的最大时间的2倍.在TCP中,这通常称为2× MSL延迟.您有时也会看到2× RTT,这大致相当.
这是所有常见TCP/IP堆栈的默认行为.2×MSL通常在30到120秒之间.(这是netstat时间段.)在此之后,堆栈假定任何恶意数据包由于过期的TTL而在途中被丢弃,因此它离开状态,允许重用该IP /端口组合.TIME_WAIT
允许新程序重新绑定到该IP /端口组合.在具有BSD套接字接口的堆栈中- 基本上所有Unix和类Unix系统,以及通过Winsock的 Windows - 您必须TIME_WAIT通过SO_REUSEADDR在调用之前设置选项来询问此行为setsockopt().
bind() 最常见的是在服务器程序中设置.
原因是,一个常见的模式是您更改服务器配置文件并需要重新启动该服务器以使其重新加载其配置.如果没有SO_REUSEADDR,SO_REUSEADDR重新启动的程序的新实例中的调用将失败,如果在您杀死它时有连接打开到上一个实例.这些连接将使TCP端口保持bind()状态30-120秒,因此您将进入上面的案例1.
安全的事情是等待TIME_WAIT这段时间,但实际上这不是一个足够大的风险,值得这样做.最好立即备份服务器,以免错过任何超过必要的传入连接.
Wil*_*and 27
SO_REUSEADDR允许您的服务器绑定到处于
TIME_WAIT状态的地址.
此套接字选项告诉内核即使此端口忙(处于TIME_WAIT状态),也要继续并重新使用它.如果它很忙,但是有另一个状态,你仍然会得到一个已经处于使用中的地址错误.如果您的服务器已关闭,然后在其端口上的套接字仍处于活动状态时立即重新启动,则此功能非常有用.
创建套接字时,您并不真正拥有它.操作系统(TCP堆栈)为您创建它,并为您提供一个句柄(文件描述符)来访问它.当您的套接字关闭时,操作系统在经历多个状态时需要一段时间"完全关闭它".正如EJP在评论中提到的,最长的延迟通常来自TIME_WAIT状态.在终止序列的最后处理边缘情况需要这个额外的延迟,并确保最后一个终止确认通过或由于超时而使另一侧自身重置.在这里您可以找到有关此状态的一些额外注意事项 主要考虑因素如下:
请记住,TCP保证所有传输的数据都将被传送,如果可能的话.当你关闭套接字时,服务器进入TIME_WAIT状态,只是为了真正确定所有数据都已通过.当套接字关闭时,双方同意通过向对方发送消息,他们将不再发送数据.这在我看来已经足够好了,握手完成后,插座应该关闭.问题是双重的.首先,无法确定最后一个ack是否成功通信.其次,网上可能存在"流浪复制品",如果交付则必须处理.
如果您尝试使用相同的ip:port对创建多个套接字非常快,则会得到"已在使用的地址"错误,因为早期的套接字不会完全释放.使用SO_REUSEADDR将消除此错误,因为它将覆盖任何先前实例的检查.
| 归档时间: |
|
| 查看次数: |
62041 次 |
| 最近记录: |