为什么http.Get(“http:// [::]:1234”)有效?

时间:2018-04-16 03:26:02

标签: 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

据我所知,“括号冒号结肠括号”表示“所有接口”。

令我惊讶的是,http.Get("http://[::]:1709")有效,它连接到网络服务器并打印出“foo”。

http://[::]:1709”如何成为有效地址?

1 个答案:

答案 0 :(得分:3)

至少在Linux系统上,这会导致与localhost建立连接。

地址::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。这是一个例子,取自我的一个网站(恰好是一个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