我在golang中有一个设置,它基本上是从OS获得一个免费端口,然后在它上面启动一个http服务器。它开始在端口注册失败时发出随机错误。我将其简化为以下程序,该程序在获取一些空闲端口后似乎出现了错误。它非常随机地发生,并且没有真正的进程在它出错的端口上运行。这对我来说没有任何意义,为什么这必须出错。任何帮助都将不胜感激。
程序输出:
..
..
58479
..
..
58867
58868
58869
..
绑定得很好!58867
绑定得很好!58868
绑定得很好!58869
..
..
..
2015/04/28 09:05:09绑定端口时出错:侦听tcp :58479: bind: address已在使用中
我确保检查出现的空闲端口不会重复。
package main
import (
"net"
"net/http"
"log"
"fmt"
)
func main() {
for {
l, _ := net.Listen("tcp", ":0")
var port = l.Addr().String()[5:]
l.Close()
fmt.Println(port)
go func() {
l1, err := net.Listen("tcp", ":"+port)
if (err != nil) {
log.Fatal("Error while binding port: ", err.Error())
} else {
fmt.Println("bound well! ", port)
}
http.Serve(l1, nil)
}()
}
}发布于 2015-04-29 01:01:24
您要做的是检查端口是否在某一点上是空闲的,然后根据它在过去是空闲的事实来尝试使用它。这是行不通的。
结果:对于for循环的每次迭代,您都会生成一个端口号,并确保它是空闲的。然后,您将生成一个打算使用此端口的例程(该端口已经释放回空闲端口池)。你真的不知道什么时候开始例行公事。它可能是在main例程( for循环)刚刚生成另一个空闲端口时被激活的--也许是同一个端口?或者可能另一个进程在这段时间内占用了这个端口。本质上,您可以在单个端口上具有竞争条件。
经过更多的研究后:
不过,这里有一个小小的警告。只要local+remote对是唯一的,就可以将两个不同的套接字绑定到同一个ip+port。我曾经写过一个
响应
关于它。所以当我创建监听器的时候
我能够得到一个“碰撞”;证明
10.0.1.11.65245 *.* LISTEN
10.0.1.11.65245 17.143.164.101.5223 ESTABLISHED现在的问题是,如果您想显式地将套接字绑定到正在使用的端口,这是不可能的。可能是因为您只能指定本地地址,而远程地址在调用侦听或连接之前是不知道的(我们现在讨论的是syscall,而不是Go接口)。换句话说,当您保留未指定的端口时,操作系统有更广泛的选择。因此,如果您获得的本地地址也被另一个套接字使用,则无法手动绑定到该地址。
如何解决它:
正如我在评论中提到的,您的服务器进程应该使用
符号,以便能够从操作系统中选择可用的资源。一旦侦听成功,就应该将地址通知给感兴趣的进程。例如,您可以通过文件或标准输出来执行此操作。
发布于 2021-03-01 08:03:56
您以前可能正在此端口上运行或调试应用程序,但它没有完全关闭。该进程可能仍挂在您的系统内存中。完全终止该进程,以及可能潜伏在阴影中的任何其他网络守护进程,并尝试再次运行您的应用程序。
如果您还没有检查过这一点,您可以使用(如果使用Linux)
,或任何GUI系统监视器,如Windows
,Gnome3's
或者KDE
搜索违规进程。
例如,我观察到Visual Studio Code的调试器/运行器实用程序( F5 /Ctrl+F5)并不总是清理进程,特别是当您太快地点击F5并且旧的调试器没有关闭时。
https://stackoverflow.com/questions/29924910
复制相似问题