如何获取http.ListenAndServe的地址

cho*_*wey 6 go

说我像这样启动服务器:

srv := http.Server{
    Addr:    ":0",
    Handler: http.FileServer(http.Dir(".")),
}
go srv.ListenAndServe()
log.Printf("Listening on ???")
Run Code Online (Sandbox Code Playgroud)

如何判断选择了哪个端口?:0旨在通过操作系统选择一个随机的短暂端口,但我需要知道哪一个被选中.

注意:我宁愿创建自己的监听器和使用srv.Listen(ln),因为我srv.ListenAndServe()有一个很好的默认(但未导出)的监听器,我想使用.

cho*_*wey 2

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

查看源码,现在是:

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)
}
Run Code Online (Sandbox Code Playgroud)

这是由于此提交,其中侦听器的“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())
Run Code Online (Sandbox Code Playgroud)