我正在编写一个测试,我希望 HTTP 服务器监听随机端口,然后连接到该端口。我写道:
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Println("foo")
})
listener, err := net.Listen("tcp", ":0")
fmt.Println(err)
httpServer := &http.Server{Handler: mux}
go httpServer.Serve(listener)
fmt.Println("http://" + listener.Addr().String())
r, err := http.Get("http://" + listener.Addr().String())
fmt.Println(r)
fmt.Println(err)
我本想写 net.Listen("tcp", "127.0.0.1:0")
但不小心写了 net.Listen("tcp", ":0")
.
对于“http://”+listener.Addr().String()
,它打印:
http://[::]:1709
据我所知,“括号冒号括号”的意思是“所有接口(interface)”。
令我惊讶的是,http.Get("http://[::]:1709")
有效,它连接到网络服务器并打印“foo”。
“http://[::]:1709”如何是一个有效的地址?
最佳答案
至少在 Linux 系统上,这会导致与本地主机建立连接。
地址::
是IN6ADDR_ANY
,通常在监听系统上任何IPv6地址的连接时使用。它类似于 INADDR_ANY
,在 IPv4 中也称为 0.0.0.0
。
有时有人尝试使用这些地址之一作为传出连接的目标地址。发生这种情况时:
当与 0.0.0.0
建立传出连接时,Linux 实际上是从 127.0.0.1
连接到 127.0.0.1
。
同样,当与 ::
建立传出连接时,Linux 实际上是从 ::1
连接到 ::1
。下面是一个例子,取 self 的一个网站(恰好是一个 IP 地址查找工具):
[error@murloc ~]$ curl -k -H "Host: myip.addr.space" https://[::]:8443/
::1
为了完整起见,这里是 IPv4 版本:
[error@murloc ~]$ curl -k -H "Host: myip.addr.space" https://0.0.0.0:8443/
127.0.0.1
请注意,这是特定于操作系统的。您会收到 an error on Windows .
关于go - 为什么 http.Get ("http://[::]:1234") 有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49849240/