【问题标题】:Why does http.Get("http://[::]:1234") work?为什么 http.Get("http://[::]:1234") 有效?
【发布时间】:2018-04-16 13:12:43
【问题描述】:

我正在编写一个测试,我希望 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”如何是有效地址?

【问题讨论】:

    标签: go ip


    【解决方案1】:

    至少在 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

    【讨论】:

    • 我在 Windows 上
    • 那有点奇怪。我本来希望你得到一个错误,就像在 IPv4 上一样。也许微软在 IPv6 中改变了一些东西。
    • pingcurlChrome 都没有连接到它,但 Go 可以。
    猜你喜欢
    • 2017-09-28
    • 1970-01-01
    • 2012-08-22
    • 2018-01-27
    • 2019-06-29
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多