go - 为什么 http.Get ("http://[::]:1234") 有效?

标签 go ip

我正在编写一个测试,我希望 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/

相关文章:

linux - 在 Iptable 中阻止网页

go - 解析数字字符串数字

mysql - Docker-Compose 服务不通信

go - 覆盖现有的 golang 结构并添加字段

go - 为什么没有渲染模板?

javascript - 如何使用javascript获取运行应用程序的主机IP和端口号

Golang 在遍历 slice panic 时删除元素

ruby - 使用 Ruby 从 IP 地址解析域

php - 网络服务器所在的欺骗国家

python - 通过主机名解析mac地址