一文看懂TCP/IP中的相關知識

前言

學習到的東西如果能以自己的方式講述出來,那就是真的理解了。記得沒有學習計算機網絡相關知識之前,對於這個模塊的東西一片混沌,什麼私有Ip,公網IP,路由器、交換機,MAC地址換七八糟的弄得我頭大,後來經過系統的學習終於整明白了,寫個博客分享一下吧!原創不易,且行且珍惜。

IP基礎知識

對這部分知識瞭解的可以跳過。

什麼是IP?

IP地址(英語:Internet Protocol)是一種在Internet上的給主機編址的方式,也稱爲網際協議地址。例如IP:119.23.27.40,被**.**分成四個部分,每個部分8bit,所以IP地址是32bit的。

IP的分類

最開始設計IP的時候並沒有想到如今的計算機如此普及,而IP的數量是有限的,爲了讓有限的IP供全球使用,想了這樣一個辦法:
根據網絡號將IP地址分爲A、B、C、D、E五類,前三類地址的範圍如下:
在這裏插入圖片描述
在這個分類中又保留了一些私有IP段,我們的計算機聯網的時候可以通過私有IP和公有IP,他們的區別就在於公有IP是唯一的,但是私有IP只需要保證在局域網內唯一,可以想想,通過這樣的技術,一個公有IP內部就可以接入很多的私有IP,每類的每個公有IP內部可以分配的私有IP數如上表中所示。根據這個最大的主機數就可以讓這些IP使用在不同的網絡佈局,A、B、C分別適用大型網絡;中型網絡;小型網絡。就如同家裏的路由器,一般家裏的聯網設備不會超過254個,一般都是192.168.1.*。

子網掩碼

通過上述的方式解決我們的IP地址不夠用的問題,但是我們發現一個小問題,C類的IP地址能鏈接的最大主機數254個,如今一個網吧都不夠分的吧!B類地址又能夠達到65534個主機,一般的企業都用不到那麼多,剩下的就浪費了。
爲了解決這個問題,引入了一項技術叫做無類型域間選路(CIDR)。使用這種技術,IP地址由兩部分組成,網絡號和主機號,比如有時候我們會看到這樣的IP:10.0.0.111/24,這種形式的就是CIDR,其中24就代表前面的24位是網絡號,另外八位就是主機號。CIDR使得子網掩碼出現了,比如255.255.255.0,子網掩碼和IP地址進行與操作就可以得到我們的網絡號。

計算機間通信

計算機通信分爲內網和需要經過公網,在將通信之前先要先明白幾個概念。

MAC地址

在將計算機間的通信之前,我們先來看看什麼是MAC地址。每臺計算機都配有網卡,每塊網卡在出廠就帶着一塊網卡,MAC地址是由16進制數字組成的物理地址,是全球唯一的,比如下圖中所示:
在這裏插入圖片描述
那爲什麼不直接用MAC地址通信?只能說想法是天真的,就像是你知道一個人的名字就可以找到他嗎?你需要他的住址,根據住址一步一步的找到他,MAC地址就相當於名字,而IP就是那個地址,在Internet中,通過對IP地址的一次一次的路由,通過各種算法的解析,才能到目標地。而MAC地址在公網中又不能拿來做路由。

ARP & 內網通信

擁有了MAC地址之後,在局域網的內部,比如A(192.168.1.2)機器要向B(192.168.1.3)發送請求。那麼A如何發送?我們知道網絡的分層:從上到下爲應用層、表示層、會話層、傳輸層、網絡層、數據鏈路層,其中IP地址是網絡層,MAC地址是數據鏈路層,兩臺機器要想通信,必須要保證下層不缺失。此處A想要和B通信,而A只有B的IP,要想通信,就必須拿到B的MAC地址,A通過ARP協議在局域網內發送廣播就可以獲取到B的MAC地址,然後在數據包中填寫MAC地址,然後將請求發送給B,從而實現局域網內部通信。

私有IP如何與公網通信

當然,私有IP是不能直接在公網中通信的,不然的話,不同局域網相同的IP不就衝突了。爲了解決私有IP通信的爲題,有了一個東西叫做網關(Gateway)。他可以根據你的目標IP是否和你在同一個網絡段而判斷出目標是否和你在一個局域網,如果在一個局域網,就像上面描述的局域網通信一樣,如果不是同一個網段的,那就比較複雜了。
比如我們的路由器,它分爲內網入口和外網入口,我們家裏的設備插入到內網入口,路由器通過DHCP(看技術詳解部分)就會給我們的設備分配內網IP,在公網入口我們需要配置運營商給的公網IP。
在這裏插入圖片描述
如圖所示:A訪問C,A首先判斷119.23.27.40是否在同一個網段,不是的話,就獲取A配置的網關的MAC地址,數據包中的內容就是:

  • 源MAC地址:A的MAC地址
  • 目標MAC:網關的MAC
  • 源IP:192.168.1.2
  • 目標IP:119.23.27.40
    然後A將數據包發送出去,網關收到數據包後,將私有的IP192.168.1.2改爲公網IP119.23.27.20,然後根據配置的路由協議選擇下一跳,圖中省略了N多哈,網關就通過ARP獲取C的MAC地址,數據包中的信息更改爲:
  • 源MAC地址:網關的MAC地址
  • 目標MAC:C的MAC
  • 源IP:119.23.27.20
  • 目標IP:119.23.27.40

C獲取請求處理請求,以同樣的方式將數據包返回給A設備,我們可以看到,私有IP上網需要通過網關轉換成公網IP,在公網IP中以直接轉發的方式進行路由,這裏還有有個問題,設備C返回請求,數據包最多隻能到達網關,因爲設備C只有網關的IP,那麼我們平時使用的時候是如何實現數據返回的呢?那麼就有種技術叫做NAT,在技術詳解部分說明。

UDP & TCP

在這裏插入圖片描述
前面講計算機之間的通信的時候主要從七層協議的數據鏈路層和網絡層講述的,但是實際在通信的時候肯定不能簡單的數據包能夠傳輸到目的地機器就可以了的,卸下MAC頭,IP頭,我們還需要根據不同應用,不同端口,數據包發送給不同的進程。而我們的UDP和TCP就是位於更高一層的傳輸層,然後我們講講這兩種協議。

UDP

UDP是面向無連接的,它不能保證數據一定到達,發到網絡中就不管了。所謂的連接,是爲了在客戶端和服務端維護連接,而建立一定的數據結構來維護雙方交互的狀態,用這樣的數據結構來保證所謂的面向連接的特性。我們可以看下UDP的頭:
在這裏插入圖片描述
在卸下IP頭裏會有個8bit的協議說明是TCP還是UDP,根據協議讀取包中的數據。無論是TCP還是UDP,內核都會通知監聽這個端口的應用讀取數據,這也是爲什麼監聽的端口不能衝突,操作系統需要根據不同的端口發送數據到不同的具體應用。UDP中目標機器收到數據過後也不會回覆消息,所以在通信的兩端都是沒有狀態的,相對於TCP來說UDP是比較簡單的。

TCP

TCP是面向連接的,它提供可靠的服務,確保每個數據包無差錯,不丟失,且按照規定次序排列好,在通信的兩端都會標記數據包的收發狀態,所以TCP是有狀態的。我們先來看下TCP的包頭與UDP有什麼差異,看了圖過後來了句wc,請問哪裏是一樣的?還真有,端口是必不可少的。
在這裏插入圖片描述
我們在寫拿java寫web項目的時候傳輸對象時需要實現序列化才能在網絡上傳輸,這裏的序號就是幹這個的,包到達目的地後能夠維持包的正確順序,確認序號可以反應包是否到達,是否需要重發,TCP不是保證包不丟失嘛,就要有相應的數據結構來支撐它的這個特性。上文還說到TCP是面向連接的,那麼TCP首先就要通過三次握手四次揮手完成TCP的連接。先認識下包頭中的位,URG:SYN:發起連接,ACK:回覆,RST:重新連接,FIN:結束連接。然後我們再來看下具體的握手揮手過程。

TCP三次握手

在這裏插入圖片描述
最開始客戶端和服務端都是closed狀態,服務端應用首先啓動,監聽端口,處於listen狀態,客戶端發起連接syn處於syn-sent狀態,服務端收到連接ACK接收SYN並且返回SYN處於SYN-RCVD狀態,客戶端收到服務端發送的SYN和ACK,發送ACK的ACK,處於established狀態,服務端收到ACK的ACK也處於established狀態,到此,客戶端和服務端分別都完成了一發一收,連接建立完成。

TCP四次揮手

在這裏插入圖片描述
客戶端A,服務端B。A要斷開連接時發送消息給B然後進入FIN_WAIT_1狀態,B接收到消息進入CLOSE_WAIT狀態,A收到B的回覆進入FIN_WAIT_2狀態,這個時候叫做半關閉。B要斷開連接時也發送消息,A收到消息後結束狀態併發送ACK(會要求A等待一段時間,讓B收到ACK或者重發),B收到後結束通訊。
當然我們只是分析的正常情況下的斷開連接的程序,如果中途發生異常,那就要另當別論了。

TCP傳輸數據包過程分析

三次握手完成之後便是我們數據包的正式傳輸,TCP可是能夠做到包不丟失、流量控制、保證有序的,那麼它如何做到,我們來看下TCP具體的實現方法。
在這裏插入圖片描述

  • LastByteAcked:第一部分和第二部分的分界線
  • LastByteSent:第二部分和第三部分的分界線
  • LastByteAcked + AdvertisedWindow:第三部分和第四部分的分界線

在這裏插入圖片描述

  • MaxRcvBuffer:最大緩存的量;
  • LastByteRead之後是已經接收了,但是還沒被應用層讀取的;
  • NextByteExpected是第一部分和第二部分的分界線。

如上圖所示,TCP中,需要在網絡中傳輸的包都是有序號的,所有的包在發送端以及接收端分爲圖中的幾個部分。首先接收端會給發送端一個窗口的大小(AdvertisedWindow),也就是圖中指明的大小,這個AdvertisedWindow size接收端如何計算的呢?看圖中,接收端是有個MaxRcVBuffer大小的,不過由於有些包已經接收確認但是應用還來不及讀取,所以AdvertisedWindow size = MaxRcvBuffer - NextByteExpected。接收端只有和第一部分是連續的纔會回覆,就算後面的已經到達也不會回覆如果包丟失也會通過某些機制(超時重傳、自適應重傳等)重新傳送。

擁塞控制

從接收端Advertised Window size的計算過程我們能發現一個問題,如果未被應用讀取的數據包變多,因爲MaxRcvBuffer肯定是固定的嘛,那麼Advertised Window size就會變小,到最後甚至爲0導致發送端暫定發送,因此TCP使用擁塞窗口和滑動窗口共同調節發送的速度(使用公式,LastByteSent - LastByteRead <= min{cwnd,rwnd})。

TCP通過擁塞控制避免包丟失和超時重傳現象,一旦出現這種現象就說明發送過快,網絡條件不好。那如何控制發送的速度,使用慢啓動:也就是將cwnd設置爲一個報文段,當收到確認過後cwnd+1,第二次就可以發動兩個,然後發送速度就是指數級的,當發送速度趕上一個值ssthresh爲65535個字節,超過這個值的時候,就減緩增加的速度,每次增加1/cwnd,當cwnd個確認過後,就增加一個cwnd,這樣就變成了線程增長,總有一天,還是會出現擁塞,然後又回到開始,cwnd設置爲1再次慢啓動。當然這樣會導致速度成爲過山車。一般在快速重傳算法情況下,cwnd會變成cwnd/2,sshthresh = cwnd,速度就不會起伏的那麼高了。現在的TCP BBR擁塞算法就是希望找到填滿管道,但是不填充緩存的這一個平衡點來達到高貸款和低延時。

技術詳解

這個部分對我們文中使用到的技術進行簡單的講述。

DHCP(動態主機配置協議)

首先,通過手動設定IP的操作絕對是可行的,不過你要不怕麻煩,如果你抱着電腦在寢室和團隊間來回用,每一次用都得配置下IP。爲了減少麻煩,就有了DHCP,感覺就像馬雲說的話 ”世界是懶人創造的“。DHCP的工作原理是這樣的:
當一臺機器A要申請IP的時候,目前A只有自己的MAC地址,它使用IP:0.0.0.0發送廣播包給IP 255.255.255.255,這個過程叫做DHCP Discover。網絡中的DHCP Server看到過後,就會分配一個設置好的共享IP給機器A,同樣使用廣播的方式,並且DHCP Server會標記這個IP不被其他的機器使用,這個過程叫做DHCP offer。如果有多個DHCP Server發送offer,機器A選擇一個進行確認,最後A就獲得了IP地址。

NAT

NAT就是網絡地址轉換,當我們私有IP需要和公網進行通信的使用,網關使用NAT將我們的私有IP轉化爲公網IP,從而使得多臺機器共享一個公網IP,這樣就能解決公網IP有限的問題。還記得下圖的例子嗎?C設備只有A的公網IP,C是如何將數據發送給A的?怎麼確認這個數據包就是返回給A的?
在這裏插入圖片描述
答案設計到NAT的具體實現,NAT的分類一般有三種靜態NAT、動態地址NAT、網絡地址端口轉換NAPT

  • 靜態NAT:私有IP與公有IP具有一一對應的關係並且記錄在靜態的轉化表中,不過這樣的話就需要大量的公網IP。
  • 動態地址NAT:公網IP較少,私有機器較多,這樣的話私有IP與公網IP就是多對一的關係,還是記錄在轉換表中,不過轉換表是動態的。
  • NAPT:這是最常用的方式,通過將私有IP映射到公網IP的不同端口上,這個端口由NAT設備選定。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章