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

我的代码如下:

package main

import (
    "net/http"
)

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

}

推荐答案

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

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.Listenernet.Addr将是动态类型*net.TCPAddr(我们可以使用type assertion获取),这是一个 struct ,有一个字段Port int.

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

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

输出示例:

Address: [::]:42039

另外,不要忘记处理返回的错误(本例中为http.ListenAndServe()).在我的示例中,我只是将其传递给panic(),因为如果一切顺利,http.LitenAndServe()http.Serve()将阻塞(因此,只有当出现错误时,它们才会返回,我将其传递给panic()).

Go相关问答推荐

如何在gocql中设置gocqlSYS标志?

杜松子wine -戈尼克背景在 children 围棋例行公事中被取消

Makefile:现有文件上没有这样的文件或目录,不加载环境变量

Go Fiber和HTMX—HX—Trigger header被更改为HX—Trigger,这不是HTMX监听的内容

在Golang中,@LATEST和@UPGRADE特殊查询有什么不同?

使用ciph.AEAD.Seal()查看内存使用情况

使用Golang的Lambda自定义al2运行时,初始化阶段超时

如何找到一个空闲的TPM句柄来保存新的密钥对对象?

这种合并排序的实现有什么问题?

Go:如何在不加载正文的情况下创建 http 代理通行证

linter 警告:返回值被忽略

为什么 0 big.Int 的 .Bytes() 值是空切片?

为什么 x/net/html Token().Attr 上的 len 在此处为空切片返回非零值?

具有相同提前返回语句的函数的不同基准测试结果

Unescape 在 rss 中两次逃脱了标题

在 golang 中联合一个接口和类型

函数的递归调用以 goroutine 和惯用方式开始,以在所有工作 goroutine 完成时继续调用者

go mod tidy 错误消息:但是 go 1.16 会 Select

(如何)我可以基于接口抽象地实现Stringer吗?

如何使用通用字段初始化匿名struct数组