gpt4 book ai didi

sockets - 为什么重新绑定(bind)到套接字会随机失败?

转载 作者:行者123 更新时间:2023-12-03 11:57:48 25 4
gpt4 key购买 nike

这个问题与 a question about getting a free port in Haskell 相关,我在其中包含了一个 getFreePort 函数,该函数检索了第一个可用端口。此功能适用于 Windows 系统,但当我在我的 Linux 机器上尝试时,它随机失败(空闲端口报告为忙)。

我已经修改了函数以尝试重新绑定(bind)到空闲地址,但它随机失败:

getFreePort :: IO Integer
getFreePort = do
sock <- socket AF_INET Stream defaultProtocol
bind sock (SockAddrInet aNY_PORT iNADDR_ANY)
port <- socketPort sock
close sock
print "Trying to rebind to the sock"
sock <- socket AF_INET Stream defaultProtocol
bind sock (SockAddrInet port 0x0100007f)
port <- socketPort sock
close sock
return (toInteger port)

我知道其他进程获取该端口存在竞争条件,但这不太可能吗?

最佳答案

一般而言,check if a resource is available and if so take it 的模式通常是反模式。每当您这样做时,您都会冒另一个进程在检查之后但在您自己实际获取资源之前获取资源的风险。

进行此类检查后,您获得的唯一信息是该资源在该特定时间点未被使用。它可能会或可能不会帮助您猜测端口的 future 状态,但您所拥有的信息在以后的任何时间都不会具有约束力。你不能假设因为资源在时间 t 是空闲的。它仍然是免费的 t+dt .即使dt非常小。当您快速询问时,它可能仍然免费的可能性更大。但仅此而已 - 也许更高的可能性。

您应该尝试获取资源并适本地处理故障。唯一可以确定端口真正空闲的方法是在您刚刚成功打开它时。然后你知道它确实是免费的。一旦你关闭它,所有的赌注都会再次关闭。

我认为您永远无法安全地检查一个端口在一个进程中是否空闲,然后假设它在另一个进程中仍然是空闲的。那没有意义。在同一个过程中甚至没有意义!

至少您必须设计一个可以来回运行的协议(protocol):

  • 这是一个刚刚免费的端口,试试
  • 不,它现在被占用了
  • 好的,这是另一个
  • 不,它现在被占用了
  • 好的,这是另一个
  • 是的,明白了,谢谢

  • 但一开始这很愚蠢。需要端口的进程应该打开它。当它已经打开了端口而不是之前,那么它应该将端口号传达给对方。

    关于sockets - 为什么重新绑定(bind)到套接字会随机失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45741572/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com