
我剛從 Mavericks 升級到 Yosemite,現在curl
看不到環回主機名稱。
設定一個簡單的http伺服器來測試:
$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
現在我可以在 Chrome 中點選 localhost:8000 了。我什至可以得到它。但在curl中,會發生這種情況:
$ curl localhost:8000
curl: (7) Failed to connect to localhost port 8000: Connection refused
然而,這有效:
$ curl 127.0.0.1:8000
我讀這個關於 wget 代理設定的答案,但這沒有幫助,因為這是有效的:
$ wget --proxy=off localhost:8000
這真的很令人沮喪,因為我的文件中列出了一些不同的環回主機名,/etc/hosts
這樣我就可以在本地開發應用程序,並且我習慣使用curl來調試它們。
我嘗試過 osx 附帶的 curl 版本:
$ curl --version
curl 7.37.1 (x86_64-apple-darwin14.0) libcurl/7.37.1 SecureTransport zlib/1.2.5
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IPv6 Largefile NTLM NTLM_WB SSL libz
$ curl localhost:8000
curl: (7) Failed to connect to localhost port 8000: Connection refused
$ curl 127.0.0.1 # works
我嘗試用brew編譯curl:
$ /usr/local/Cellar/curl/7.38.0/bin/curl --version
curl 7.38.0 (x86_64-apple-darwin14.0.0) libcurl/7.38.0 SecureTransport zlib/1.2.5
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: IPv6 Largefile NTLM NTLM_WB SSL libz
$ /usr/local/Cellar/curl/7.38.0/bin/curl localhost:8000
curl: (7) Failed to connect to localhost port 8000: Connection refused
$ /usr/local/Cellar/curl/7.38.0/bin/curl 127.0.0.1:8000 # works
答案1
我剛剛透過註解掉 /etc/hosts 檔案中的 IPv6 環回行之一使其工作:
#fe80::1%lo0 localhost
現在我所有的環回主機名稱都可以工作,而不僅僅是 localhost。我想知道這是怎麼回事?
答案2
選擇(不需要 sudo 或修改/etc/hosts
)- 始終使用ipv4,直到curl變得更聰明。
$ echo '--ipv4' >> ~/.curlrc
(然後一切都會按預期進行)
答案3
首先,0.0.0.0
是一個特殊位址,意思是「任何 IPv4 位址」。
套接字可以綁定到 IPv4 或 IPv6 協定。如果套接字綁定到0.0.0.0
,則表示它將偵聽任何嘗試連接到它的 IPv4,並將表示如下:
$ nc -l 0.0.0.0 8085
$ lsof -i4 -Pnl | grep 8085
nc 23994 [xxx] 3u IPv4 [xxx] 0t0 TCP *:8085 (LISTEN)
該*
符號相當於0.0.0.0
IPv4 上的符號。
對於 IPv6:
$ nc -l :: 8085
$ lsof -i6 -Pnl | grep 8085
nc 24145 [xxx] 3u IPv6 [xxx] 0t0 TCP *:8085 (LISTEN)
該*
符號相當於::
IPv6 上的,如官方規範所示。
原因是curl
嘗試解析為localhost
中的隨機條目/etc/hosts
,如 @NickRetallack 所提到的,該條目是在預設模式下curl
解析時選擇的條目localhost
(假設是 IPv6 或 IPv4,無論先解析哪一個)。
--ipv4
正如 @CharlesHebdough 所建議的那樣,強制其進入模式將curl
解析localhost
為(假設in127.0.0.1
沒有其他 IPv4 條目)。localhost
/etc/hosts
每個實施都會localhost
按照他們的意願解決,這就是為什麼你使用不同的工具時斷時續地取得成功的原因。
為了盡可能準確,請使用127.0.0.1
localhost 代替,但它會將您綁定到 IPv4。localhost
使您可以靈活地在 IPv6 和 IPv4 協定中工作,但是在某些實作中您可能會遇到麻煩,例如在curl
.