如何在 http 中使用下一个可用端口.倾听和服务



我写了一个简单的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不直接提供对端口的访问权限,但由于我们使用网络流创建了tcpnet.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

最新更新