如何使用 http.ListenAndServe 中的下一个可用端口

How to use next available port in http.ListenAndServe

我编写了一个简单的 Web 服务器来侦听端口 8080。但我不想使用硬编码的端口号。我想要的是我的服务器侦听任何可用端口。我想知道我的 Web 服务器正在侦听的端口号。

我的代码如下:

package main

import (
    "net/http"
)

func main() {       
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)

}

您可以使用端口 0 表示您没有指定确切的端口,但您希望系统选择一个空闲的可用端口:

http.ListenAndServe(":0", nil)

问题是您无法找出分配的端口。所以你需要创建 net.Listener yourself (using the net.Listen() function), and manually pass it to http.Serve():

listener, err := net.Listen("tcp", ":0")
if err != nil {
    panic(err)
}

fmt.Println("Using port:", listener.Addr().(*net.TCPAddr).Port)

panic(http.Serve(listener, nil))

示例输出:

Using port: 42039

如您所见,您可以从 net.Listener 访问分配的端口,从它的 net.Addr address (acquired by its Addr() method). net.Addr does not directly give access to the port, but since we created the net.Listener using tcp network stream, the net.Addr will be of dynamic type *net.TCPAddr (which we can acquire with a type assertion),它是一个结构体并且有一个字段 Port int.

请注意,如果您不需要应用程序中的端口(例如,您只想自己显示它),则不需要类型断言,您可以只打印 listener.Addr()(这将在末尾包含端口):

fmt.Println("Address:", listener.Addr())

示例输出:

Address: [::]:42039

也不要忘记处理 returned 错误(在本例中为 http.ListenAndServe())。在我的示例中,我只是将它传递给 panic(),因为如果一切顺利,http.LitenAndServe()http.Serve() 会阻塞(所以如果出现错误,它们只会 return,我将错误传递给 panic()).

我进入此页面是因为我想在随机端口上启动一个新服务器以进行测试。后来我了解到 httptesthttps://golang.org/pkg/net/http/httptest/ ,它在管理用于测试的临时 HTTP 服务器方面做得更好。