當前位置:首頁 > 公眾號精選 > CPP開發(fā)者
[導讀]你女神愛不愛你,你問她,她可能不會告訴你。但網(wǎng)通不通,你ping一下就知道了??赡芸吹綐祟},你就知道答案了,但是你了解背后的原因嗎?那如果把127.0.0.1換成0.0.0.0或localhost會怎么樣呢?你知道這幾個IP有什么區(qū)別嗎?以前面試的時候就遇到過這個問題,大家看個動...

你女神愛不愛你,你問她,她可能不會告訴你。

但網(wǎng)通不通,你 ping 一下就知道了。

可能看到標題,你就知道答案了,但是你了解背后的原因嗎?那如果把 127.0.0.1 換成 0.0.0.0localhost 會怎么樣呢?你知道這幾個IP有什么區(qū)別嗎?

以前面試的時候就遇到過這個問題,大家看個動圖了解下面試官和我當時的場景,求當時小白的心里陰影面積。

話不多說,我們直接開車。

拔掉網(wǎng)線,斷網(wǎng)。

然后在控制臺輸入ping 127.0.0.1

$?ping?127.0.0.1
PING?127.0.0.1?(127.0.0.1):?56?data?bytes
64?bytes?from?127.0.0.1:?icmp_seq=0?ttl=64?time=0.080?ms
64?bytes?from?127.0.0.1:?icmp_seq=1?ttl=64?time=0.093?ms
64?bytes?from?127.0.0.1:?icmp_seq=2?ttl=64?time=0.074?ms
64?bytes?from?127.0.0.1:?icmp_seq=3?ttl=64?time=0.079?ms
64?bytes?from?127.0.0.1:?icmp_seq=4?ttl=64?time=0.079?ms
^C
---?127.0.0.1?ping?statistics?---
5?packets?transmitted,?5?packets?received,?0.0%?packet?loss
round-trip?min/avg/max/stddev?=?0.074/0.081/0.093/0.006?ms
說明,拔了網(wǎng)線,ping 127.0.0.1 ?是能ping通的。

其實這篇文章看到這里,標題前半個問題已經(jīng)被回答了。但是我們可以再想深一點。

為什么斷網(wǎng)了還能 ping127.0.0.1 呢?

這能說明你不用交網(wǎng)費就能上網(wǎng)嗎?

不能。

首先我們需要進入基礎科普環(huán)節(jié)。

不懂的同學看了就懂了,懂的看了就當查漏補缺吧。

什么是127.0.0.1

首先,這是個 IPV4 地址。

IPV4 地址有 32 位,一個字節(jié)有 8 位,共 4 個字節(jié)。

其中127 開頭的都屬于回環(huán)地址,也是 IPV4 的特殊地址,沒什么道理,就是人為規(guī)定的。

127.0.0.1是眾多回環(huán)地址中的一個。之所以不是 127.0.0.2 ,而是 127.0.0.1,是因為源碼里就是這么定義的,也沒什么道理。

/*?Address?to?loopback?in?software?to?local?host.??*/
#define????INADDR_LOOPBACK?????0x7f000001??/*?127.0.0.1???*/
回環(huán)地址
IPv4 的地址是 32 位的,2的32次方,大概是40 億。地球光人口就76億了,40億IP這點量,塞牙縫都不夠,實際上IP也確實用完了。

所以就有了IPV6, IPv6 的地址是 128 位的,大概是2的128次方≈10的38次方。據(jù)說地球的沙子數(shù)量大概是 10的23次方,所以IPV6的IP可以認為用不完。

IPV4以8位一組,每組之間用 . 號隔開。

IPV6就以16位為一組,每組之間用 : 號隔開。如果全是0,那么可以省略不寫。

ipv6回環(huán)地址
在IPV4下的回環(huán)地址是 127.0.0.1,在IPV6下,表達為 ::1 。中間把連續(xù)的0給省略了,之所以不是7個 冒號,而是2個冒號: , 是因為一個 IPV6 地址中只允許出現(xiàn)?次兩個連續(xù)的冒號。

多說一句:在IPV4下用的是 ping 127.0.0.1 命令。在IPV6下用的是 ping6 ?::1 命令。

什么是 ping

ping 是應用層命令,可以理解為它跟游戲或者聊天軟件屬于同一層。只不過聊天軟件可以收發(fā)消息,還能點個贊什么的,有很多復雜的功能。而 ping 作為一個小軟件,它的功能比較簡單,就是嘗試發(fā)送一個小小的消息到目標機器上,判斷目的機器是否可達,其實也就是判斷目標機器網(wǎng)絡是否能連通。

ping應用的底層,用的是網(wǎng)絡層的ICMP協(xié)議。

IP和ICMP和Ping所在分層
雖然ICMP協(xié)議和IP協(xié)議都屬于網(wǎng)絡層協(xié)議,但其實ICMP也是利用了IP協(xié)議進行消息的傳輸。

ip和icmp的關系
所以,大家在這里完全可以簡單的理解為 ping 某個IP 就是往某個IP地址發(fā)個消息。

TCP發(fā)數(shù)據(jù)和ping的區(qū)別

一般情況下,我們會使用 TCP 進行網(wǎng)絡數(shù)據(jù)傳輸,那么我們可以看下它和 ping 的區(qū)別。

ping和普通發(fā)消息的關系
ping和其他應用層軟件都屬于應用層。

那么我們橫向對比一下,比方說聊天軟件,如果用的是TCP的方式去發(fā)送消息。

為了發(fā)送消息,那就得先知道往哪發(fā)。linux里萬物皆文件,那你要發(fā)消息的目的地,也是個文件,這里就引出了socket 的概念。

要使用 socket , 那么首先需要創(chuàng)建它。

在 TCP 傳輸中創(chuàng)建的方式是 ?socket(AF_INET, SOCK_STREAM, 0);,其中 AF_INET 表示將使用 IPV4 里 host:port 的方式去解析待會你輸入的網(wǎng)絡地址。SOCK_STREAM 是指使用面向字節(jié)流的 TCP 協(xié)議,工作在傳輸層。

創(chuàng)建好了 socket 之后,就可以愉快的把要傳輸?shù)臄?shù)據(jù)寫到這個文件里。調(diào)用 socket 的sendto接口的過程中進程會從用戶態(tài)進入到內(nèi)核態(tài),最后會調(diào)用到 sock_sendmsg 方法。

然后進入傳輸層,帶上TCP頭。網(wǎng)絡層帶上IP頭,數(shù)據(jù)鏈路層帶上 MAC頭等一系列操作后。進入網(wǎng)卡的發(fā)送隊列 ring buffer ,順著網(wǎng)卡就發(fā)出去了。

回到 ping , 整個過程也基本跟 TCP 發(fā)數(shù)據(jù)類似,差異的地方主要在于,創(chuàng)建 socket 的時候用的是 ?socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)SOCK_RAW 是原始套接字 ,工作在網(wǎng)絡層, 所以構建ICMP(網(wǎng)絡層協(xié)議)的數(shù)據(jù),是再合適不過了。ping 在進入內(nèi)核態(tài)后最后也是調(diào)用的 ?sock_sendmsg 方法,進入到網(wǎng)絡層后加上ICMP和IP頭后,數(shù)據(jù)鏈路層加上MAC頭,也是順著網(wǎng)卡發(fā)出。因此 本質(zhì)上ping 跟 普通應用發(fā)消息 在程序流程上沒太大差別。

這也解釋了為什么當你發(fā)現(xiàn)懷疑網(wǎng)絡有問題的時候,別人第一時間是問你能ping通嗎?因為可以簡單理解為ping就是自己組了個數(shù)據(jù)包,讓系統(tǒng)按著其他軟件發(fā)送數(shù)據(jù)的路徑往外發(fā)一遍,能通的話說明其他軟件發(fā)的數(shù)據(jù)也能通。

為什么斷網(wǎng)了還能 ping 通 127.0.0.1

前面提到,有網(wǎng)的情況下,ping 最后是通過網(wǎng)卡將數(shù)據(jù)發(fā)送出去的。

那么斷網(wǎng)的情況下,網(wǎng)卡已經(jīng)不工作了,ping 回環(huán)地址卻一切正常,我們可以看下這種情況下的工作原理。

ping回環(huán)地址
從應用層到傳輸層再到網(wǎng)絡層。這段路徑跟ping外網(wǎng)的時候是幾乎是一樣的。到了網(wǎng)絡層,系統(tǒng)會根據(jù)目的IP,在路由表中獲取對應的路由信息,而這其中就包含選擇哪個網(wǎng)卡把消息發(fā)出。

當發(fā)現(xiàn)目標IP是外網(wǎng)IP時,會從"真網(wǎng)卡"發(fā)出。

當發(fā)現(xiàn)目標IP是回環(huán)地址時,就會選擇本地網(wǎng)卡。

本地網(wǎng)卡,其實就是個"假網(wǎng)卡",它不像"真網(wǎng)卡"那樣有個ring buffer什么的,"假網(wǎng)卡"會把數(shù)據(jù)推到一個叫 input_pkt_queue 的 鏈表 中。這個鏈表,其實是所有網(wǎng)卡共享的,上面掛著發(fā)給本機的各種消息。消息被發(fā)送到這個鏈表后,會再觸發(fā)一個軟中斷。

專門處理軟中斷的工具人"ksoftirqd" (這是個內(nèi)核線程),它在收到軟中斷后就會立馬去鏈表里把消息取出,然后順著數(shù)據(jù)鏈路層、網(wǎng)絡層等層層往上傳遞最后給到應用程序。

工具人ksoftirqd
ping 回環(huán)地址和通過TCP等各種協(xié)議發(fā)送數(shù)據(jù)到回環(huán)地址都是走這條路徑。整條路徑從發(fā)到收,都沒有經(jīng)過"真網(wǎng)卡"。之所以127.0.0.1叫本地回環(huán)地址,可以理解為,消息發(fā)出到這個地址上的話,就不會出網(wǎng)絡,在本機打個轉就又回來了。所以斷網(wǎng),依然能 ping127.0.0.1。

ping回環(huán)地址和ping本機地址有什么區(qū)別

我們在mac里執(zhí)行 ifconfig

$?ifconfig
lo0:?flags=8049?mtu?16384
????inet?127.0.0.1?netmask?0xff000000
????...
en0:?flags=8863?mtu?1500
????inet?192.168.31.6?netmask?0xffffff00?broadcast?192.168.31.255
????...
能看到 lo0,表示本地回環(huán)接口,對應的地址,就是我們前面提到的 127.0.0.1 ,也就是回環(huán)地址。

和 eth0,表示本機第一塊網(wǎng)卡,對應的IP地址是192.168.31.6,管它叫本機IP。

之前一直認為ping本機IP的話會通過"真網(wǎng)卡"出去,然后遇到第一個路由器,再發(fā)回來到本機。

為了驗證這個說法,可以進行抓包,但結果跟上面的說法并不相同。

ping 127.0.0.1

ping 本機地址
可以看到 ping 本機IP 跟 ping 回環(huán)地址一樣,相關的網(wǎng)絡數(shù)據(jù),都是走的 ?lo0,本地回環(huán)接口,也就是前面提到的"假網(wǎng)卡"。

只要走了本地回環(huán)接口,那數(shù)據(jù)都不會發(fā)送到網(wǎng)絡中,在本機網(wǎng)絡協(xié)議棧中兜一圈,就發(fā)回來了。因此 ping回環(huán)地址和ping本機地址沒有區(qū)別。

127.0.0.1 和 localhost 以及 0.0.0.0 有區(qū)別嗎

回到文章開頭動圖里的提問,算是面試八股文里的老??土?。

以前第一次用 nginx 的時候,發(fā)現(xiàn)用這幾個 IP,都能正常訪問到 nginx 的歡迎網(wǎng)頁。一度認為這幾個 IP 都是一樣的。

訪問127.0.0.1:80
訪問localhost:80
訪問0.0.0.0:80
訪問本機的IP地址
但本質(zhì)上還是有些區(qū)別的。

首先 localhost 就不叫 IP,它是一個域名,就跟 "baidu.com",是一個形式的東西,只不過默認會把它解析為 127.0.0.1 ,當然這可以在 /etc/hosts 文件下進行修改。

所以默認情況下,使用 localhost ?跟使用 ?127.0.0.1 ?確實是沒區(qū)別的。

其次就是 0.0.0.0,執(zhí)行 ping 0.0.0.0 ?,是會失敗的,因為它在IPV4中表示的是無效的目標地址。

$?ping?0.0.0.0
PING?0.0.0.0?(0.0.0.0):?56?data?bytes
ping:?sendto:?No?route?to?host
ping:?sendto:?No?route?to?host
但它還是很有用處的,回想下,我們啟動服務器的時候,一般會 listen 一個 IP 和端口,等待客戶端的連接。

如果此時 listen 的是本機的 0.0.0.0 , 那么它表示本機上的所有IPV4地址。

/*?Address?to?accept?any?incoming?messages.?*/
#define????INADDR_ANY??????((unsigned?long?int)?0x00000000)?/*?0.0.0.0???*/
舉個例子。剛剛提到的 127.0.0.1192.168.31.6 ,都是本機的IPV4地址,如果監(jiān)聽 0.0.0.0 ?,那么用上面兩個地址,都能訪問到這個服務器。

當然, 客戶端 connect 時,不能使用 0.0.0.0 。必須指明要連接哪個服務器IP。

總結

  • 127.0.0.1 是回環(huán)地址。localhost是域名,但默認等于 127.0.0.1。

  • ping 回環(huán)地址和 ping 本機地址,是一樣的,走的是lo0 "假網(wǎng)卡",都會經(jīng)過網(wǎng)絡層和數(shù)據(jù)鏈路層等邏輯,最后在快要出網(wǎng)卡前狠狠拐了個彎, 將數(shù)據(jù)插入到一個鏈表后就軟中斷通知 ksoftirqd 來進行收數(shù)據(jù)的邏輯,壓根就不出網(wǎng)絡。所以斷網(wǎng)了也能 ping 通回環(huán)地址。

  • 如果服務器 listen 的是 0.0.0.0,那么此時用127.0.0.1和本機地址都可以訪問到服務。

參考資料

《127.0.0.1 之本機網(wǎng)絡通信過程知多少 ?!》

- EOF -

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉