我写了一个简单的Web服务器来监听端口8080。但我不想使用硬编码的端口号。我想要的是我的服务器侦听任何可用的端口。我想知道我的 Web 服务器正在侦听的端口号。
我的代码如下:
package main
import (
"net/http"
)
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
您可以使用端口0
来指示您没有指定确切的端口,但您希望系统选择一个可用的可用端口:
http.ListenAndServe(":0", nil)
这样做的问题是您将无法找出分配的端口。所以你需要自己创建net.Listener
(使用net.Listen()
函数),并手动将其传递给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
地址(通过其Addr()
方法获取)访问分配的端口。net.Addr
不直接提供对端口的访问权限,但由于我们使用网络流创建了tcp
net.Listener
,因此net.Addr
将是动态类型*net.TCPAddr
(我们可以通过类型断言获取),它是一个结构并具有字段Port int
。
请注意,如果您的应用程序中不需要该端口(例如,您只想自己显示它),则不需要类型断言,您只需打印listener.Addr()
(末尾将包含端口):
fmt.Println("Address:", listener.Addr())
示例输出:
Address: [::]:42039
另外不要忘记处理返回的错误(在这种情况下http.ListenAndServe()
)。在我的示例中,我只是将其传递给panic()
因为如果一切顺利,http.LitenAndServe()
和http.Serve()
块(因此它们仅在出现错误时才返回,我将其传递给panic()
)。
我登陆此页面是因为我想在随机端口上启动新服务器以进行测试。我后来了解了httptest
包 https://golang.org/pkg/net/http/httptest/,它在管理用于测试的临时 HTTP 服务器方面做得更好。
包 https://pkg.go.dev/net/http/httptest 支持随机端口上的HTTP服务器。
package main
import (
"fmt"
"net/http"
"net/http/httptest"
)
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
})
server := httptest.NewServer(handler)
defer server.Close()
fmt.Println("Server started", server.URL)
}
示例输出
Server started http://127.0.0.1:54926