首页 文章

SO_REUSEADDR(setsockopt选项)是什么意思 - Linux? [重复]

提问于
浏览
49

这个问题在这里已有答案:

从手册页:

SO_REUSEADDR指定在验证提供给bind()的地址时使用的规则应允许重用本地地址(如果协议支持此地址) . 此选项采用int值 . 这是一个布尔选项

我应该什么时候使用它?为什么“重用本地地址”给出了?

3 回答

  • 106

    TCP的主要设计目标是在数据包丢失,数据包重新排序和 - 密钥,这里 - 数据包复制时允许可靠的数据通信 .

    它是一个在连接关闭后发生的边缘情况 . 如果在会话结束时发送的数据包被复制并延迟,以便在延迟数据包之前the 4-way shutdown数据包到达接收器会发生什么?堆栈尽职地关闭其连接 . 然后,延迟的重复数据包显示出来 . 堆栈应该做什么?

    更重要的是,如果拥有该连接的程序立即死亡,那么它应该怎么办?那么另一个启动需要相同的IP地址和TCP端口号?

    有几个选择:

    • 禁止重用该IP /端口组合至少是数据包在飞行中的最大时间的2倍 . 在TCP中,这通常称为2×MSL延迟 . 你有时也看到2×RTT,这大致相当 .

    这是所有常见TCP / IP堆栈的默认行为 . 2×MSL通常在30到120秒之间 . (这是TIME_WAIT期间 . )在此之后,堆栈假定由于过期的TTLs而在途中丢弃了任何恶意数据包,因此它将离开 TIME_WAIT 状态,允许重用该IP /端口组合 .

    • 允许新程序重新绑定到该IP /端口组合 . 在带有BSD sockets接口的堆栈中 - 基本上所有的Unix和类Unix系统,以及通过Winsock的Windows - 你必须通过在调用bind()之前通过setsockopt()设置 SO_REUSEADDR 选项来要求这种行为 .

    SO_REUSEADDR 最常在服务器程序中设置 .

    原因是,一个常见的模式是您更改服务器配置文件并需要重新启动该服务器以使其重新加载其配置 . 如果没有 SO_REUSEADDR ,重新启动的程序的新实例中的 bind() 调用将失败,如果在您杀死它时有连接打开到上一个实例 . 这些连接将使 TIME_WAIT 状态的TCP端口保持30-120秒,因此您将进入上面的案例1 .

    安全的事情是等待 TIME_WAIT 期间,但实际上这不值得这样做 . 最好立即备份服务器,以免错过任何超过必要的传入连接 .

  • 23

    SO_REUSEADDR允许您的服务器绑定到处于TIME_WAIT状态的地址 .

    此套接字选项告诉内核即使此端口忙(处于TIME_WAIT状态),也要继续并重新使用它 . 如果它很忙,但是有另一个状态,你仍然会得到一个已经处于使用中的地址错误 . 如果您的服务器已关闭,然后在其端口上的套接字仍处于活动状态时立即重新启动,则此功能非常有用 .

    来自unixguide.net

  • 7

    创建套接字时,您并不真正拥有它 . 操作系统(TCP堆栈)为您创建它,并为您提供一个句柄(文件描述符)来访问它 . 当您的套接字关闭时,操作系统在经历多个状态时需要一段时间才能"fully close it" . 正如EJP在评论中提到的,最长的延迟通常来自TIME_WAIT状态 . 在终止序列的最后处理边缘情况需要这个额外的延迟,并确保最后一个终止确认通过或由于超时而使另一侧自身重置 . Here you can find关于这种状态的一些额外考虑 . 主要考虑因素如下:

    请记住,TCP保证所有传输的数据都将被传送,如果可能的话 . 当你关闭套接字时,服务器进入TIME_WAIT状态,只是为了真正确定所有数据都已通过 . 当套接字关闭时,双方同意通过向对方发送消息,他们将不再发送数据 . 这在我看来已经足够好了,握手完成后,插座应该关闭 . 问题是双重的 . 首先,无法确定最后一个ack是否成功通信 . 其次,可能存在“游荡重复”留在网上,如果交付必须处理 .

    如果您尝试使用相同的ip:port对创建多个套接字非常快,则会得到“已在使用的地址”错误,因为早期的套接字不会完全释放 . 使用SO_REUSEADDR将消除此错误,因为它将覆盖任何先前实例的检查 .

相关问题