如何获取http.ListenAndServe的地址

时间:2015-07-26 00:44:48

标签: go

说我像这样启动服务器:

onOpen

如何判断选择了哪个端口? srv := http.Server{ Addr: ":0", Handler: http.FileServer(http.Dir(".")), } go srv.ListenAndServe() log.Printf("Listening on ???") 旨在通过操作系统选择随机短暂端口,但我需要知道选择了哪一个。

注意:我希望创建我自己的侦听器并使用:0,因为srv.Listen(ln)具有良好的默认值(但未导出)我想要使​​用的听众。

3 个答案:

答案 0 :(得分:2)

  

我不想创建自己的侦听器并使用srv.Listen(ln),因为srv.ListenAndServe()有一个我想要使用的好的默认(但未导出)侦听器。

为什么不呢? ListenAndServe()非常容易实现。您可以自己read the source code

func (srv *Server) ListenAndServe() error {
    addr := srv.Addr
    if addr == "" {
        addr = ":http"
    }
    ln, err := net.Listen("tcp", addr)
    if err != nil {
        return err
    }
    return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})
}

答案是你需要使用自己编写的ListenAndServe()来为你提供所需的信息。然而,它比你想象的容易得多。整个事情不超过20行(假设你想用tcpKeepAliveListener设置keep-alives。)

答案 1 :(得分:2)

从Go 1.14.1开始,net/http不再包装TCP侦听器!

现在看documentation,是:

func (srv *Server) ListenAndServe() error {
    if srv.shuttingDown() {
        return ErrServerClosed
    }
    addr := srv.Addr
    if addr == "" {
        addr = ":http"
    }
    ln, err := net.Listen("tcp", addr)
    if err != nil {
        return err
    }
    return srv.Serve(ln)
}

这是由于source code所致,其中侦听器的“ keepalive”部分已移至标准net程序包,并且默认情况下已打开。

所以,不用担心!只需创建自己的侦听器即可。


示例

ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
    return err
}
go srv.Serve(ln)
log.Printf("Listening on %s", ln.Addr().String())

答案 2 :(得分:0)

您可以在配置服务器地址之前选择空闲端口。获得自由端口的更简单方法是创建一个监听器,这样您就可以在Stephen建议之后获得相同的结果。

func GetFreePort() (int, error) {
    ln, err := net.Listen("tcp", ":0")
    if err != nil {
        return 0, err
    }
    err = ln.Close()
    if err != nil {
        return 0, err
    }
    return ln.Addr().(*net.TCPAddr).Port, nil
}

这是一个完整的示例https://play.golang.org/p/bG4OpmQbz9s