2 回答
TA贡献1946条经验 获得超4个赞
您所做的是检查端口是否在某一时刻空闲,然后根据过去它是空闲的事实尝试使用它。这是行不通的。
会发生什么:在 for 循环的每次迭代中,您都会生成一个端口号并确保它是空闲的。然后您生成一个打算使用这个端口的例程(它已经被释放回空闲端口池)。你真的不知道这个例程什么时候开始。它可能在主例程(for 循环)刚刚生成另一个空闲端口时被激活——也许又是同一个?或者也许另一个进程同时占用了这个端口。本质上,您可以在单个端口上存在竞争条件。
经过更多的研究:
不过有一个小警告。只要本地+远程对是唯一的,两个不同的套接字就可以绑定到同一个ip+端口。因此,当我创建侦听器时,:0
我能够获得“碰撞”;证明netstat -an
:
10.0.1.11.65245 *.* LISTEN 10.0.1.11.65245 17.143.164.101.5223 ESTABLISHED
现在,问题是如果您想显式绑定正在使用的端口的套接字,这是不可能的。可能是因为您只能指定本地地址,而在调用侦听或连接之前不会知道远程地址(我们现在谈论的是系统调用,而不是 Go 接口)。换句话说,当您不指定端口时,操作系统有更广泛的选择。因此,如果发生这种情况,您的本地地址也正被另一个套接字使用,您将无法手动绑定到它。
如何解决:
正如我在评论中提到的,您的服务器进程应该使用:0
符号,以便能够从操作系统中选择可用资源。一旦它开始侦听,就应该向感兴趣的进程宣布地址。例如,您可以通过文件或标准输出来实现。
TA贡献1906条经验 获得超10个赞
可能您之前在此端口上运行或调试应用程序,并且它没有完全关闭。该进程可能仍在您的系统内存中。完全终止该进程,以及可能潜伏在阴影中的任何其他网络守护进程,然后再次尝试运行您的应用程序。
如果您还没有检查过这一点,您可以使用(如果使用 Linux)top
、htop
或任何 GUI 系统监视器,如 Windows' Task Manager
、Gnome3System Monitor
或 KDE'sKSysGuard
来搜索有问题的进程。
例如,我观察到 Visual Studio Code 的调试器/运行器实用程序 (F5/Ctrl+F5) 并不总是清理进程,特别是如果您按 F5 太快并且旧的调试器没有关闭。
- 2 回答
- 0 关注
- 196 浏览
添加回答
举报