首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >绑定地址已在使用中的golang错误,即使端口上未运行任何内容也是如此

绑定地址已在使用中的golang错误,即使端口上未运行任何内容也是如此
EN

Stack Overflow用户
提问于 2015-04-29 00:27:42
回答 2查看 15.3K关注 0票数 4

我在golang中有一个设置,它基本上是从OS获得一个免费端口,然后在它上面启动一个http服务器。它开始在端口注册失败时发出随机错误。我将其简化为以下程序,该程序在获取一些空闲端口后似乎出现了错误。它非常随机地发生,并且没有真正的进程在它出错的端口上运行。这对我来说没有任何意义,为什么这必须出错。任何帮助都将不胜感激。

程序输出:

..

..

58479

..

..

58867

58868

58869

..

绑定得很好!58867

绑定得很好!58868

绑定得很好!58869

..

..

..

2015/04/28 09:05:09绑定端口时出错:侦听tcp :58479: bind: address已在使用中

我确保检查出现的空闲端口不会重复。

代码语言:javascript
复制
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)
            }()
    }
}
EN

回答 2

Stack Overflow用户

发布于 2015-04-29 01:01:24

您要做的是检查端口是否在某一点上是空闲的,然后根据它在过去是空闲的事实来尝试使用它。这是行不通的。

结果:对于for循环的每次迭代,您都会生成一个端口号,并确保它是空闲的。然后,您将生成一个打算使用此端口的例程(该端口已经释放回空闲端口池)。你真的不知道什么时候开始例行公事。它可能是在main例程( for循环)刚刚生成另一个空闲端口时被激活的--也许是同一个端口?或者可能另一个进程在这段时间内占用了这个端口。本质上,您可以在单个端口上具有竞争条件。

经过更多的研究后:

不过,这里有一个小小的警告。只要local+remote对是唯一的,就可以将两个不同的套接字绑定到同一个ip+port。我曾经写过一个

响应

关于它。所以当我创建监听器的时候

我能够得到一个“碰撞”;证明

代码语言:javascript
复制
10.0.1.11.65245        *.*                    LISTEN
10.0.1.11.65245        17.143.164.101.5223    ESTABLISHED

现在的问题是,如果您想显式地将套接字绑定到正在使用的端口,这是不可能的。可能是因为您只能指定本地地址,而远程地址在调用侦听或连接之前是不知道的(我们现在讨论的是syscall,而不是Go接口)。换句话说,当您保留未指定的端口时,操作系统有更广泛的选择。因此,如果您获得的本地地址也被另一个套接字使用,则无法手动绑定到该地址。

如何解决它:

正如我在评论中提到的,您的服务器进程应该使用

符号,以便能够从操作系统中选择可用的资源。一旦侦听成功,就应该将地址通知给感兴趣的进程。例如,您可以通过文件或标准输出来执行此操作。

票数 9
EN

Stack Overflow用户

发布于 2021-03-01 08:03:56

您以前可能正在此端口上运行或调试应用程序,但它没有完全关闭。该进程可能仍挂在您的系统内存中。完全终止该进程,以及可能潜伏在阴影中的任何其他网络守护进程,并尝试再次运行您的应用程序。

如果您还没有检查过这一点,您可以使用(如果使用Linux)

,或任何GUI系统监视器,如Windows

,Gnome3's

或者KDE

搜索违规进程。

例如,我观察到Visual Studio Code的调试器/运行器实用程序( F5 /Ctrl+F5)并不总是清理进程,特别是当您太快地点击F5并且旧的调试器没有关闭时。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29924910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档