43.Linux網絡編程--TCP IP原理深入剖析

前幾節我們說了一下我們TCP/IP的一些發展歷史,分層及各層一些關鍵的協議的一個簡單介紹,然後詳細的進行了TCP,UDP的一個網絡編程。想要進一步的深入理解,編程上更遊刃有餘的話,需要詳細的分析一下TCP/IP協議的一些關鍵機制。

 

一. wirshark 工具

學習網絡編程的人,必然會接觸這個工具,畢竟網絡協議棧太大,太複雜,不抓包分析一下,又怎麼能理解的了其中的原理。wireshark是非常流行的網絡封包分析軟件,功能十分強大。可以截取各種網絡封包,顯示網絡封包的詳細信息。

安裝過程我們就不說了,安裝之後打開軟件。

然後點擊Caputre->Interfaces.. 出現下面對話框,選擇正確的網卡。然後點擊"Start"按鈕, 開始抓包。(我們的虛擬機會虛擬出個網卡)

我們可以通過設置顯示過濾器來選擇我們想要監控的程序。

過濾器(顯示過濾器和捕獲過濾器)會幫助我們在大量的數據中迅速找到我們需要的信息。

 

下面我們就詳細說一下過濾器的規則:

1.過濾ip(來源ip或者目標IP等於某個ip)

例:

  • ip.src eq 192.168.0.129 
  • ip.dst eq 192.168.0.129
  • ip.addr eq 192.168.0.129 

 

2.過濾端口

例:

  • tcp.port eq 80 // 不管端口是來源的還是目標的都顯示
  • tcp.port == 80
  • tcp.port eq 80 or udp.port eq 80
  • tcp.dstport == 80 // 只顯tcp協議的目標端口80
  • tcp.srcport == 80 // 只顯tcp協議的來源端口80

過濾端口範圍

tcp.port >= 1 and tcp.port <= 80

 

3.過濾協議

例:

ip

udp

tcp

http

 

4.過濾MAC

  • eth.dst == A0:00:00:04:C5:84 // 過濾目標mac
  • eth.src eq A0:00:00:04:C5:84 // 過濾來源mac
  • eth.dst==A0:00:00:04:C5:84
  • eth.dst==A0-00-00-04-C5-84
  • eth.addr eq A0:00:00:04:C5:84 // 過濾來源MAC和目標MAC都等於A0:00:00:04:C5:84

 

5.包長度過濾

例子:

  • udp.length == 26 這個長度是指udp本身固定長度8加上udp下面數據包之和
  • tcp.len >= 7   指的是TCP下面數據包,不包括tcp本身
  • ip.len == 94 除了以太網頭固定長度14,其它都算是ip.len,即從ip本身到最後

 

6.http模式過濾

 

7.tcp參數過濾

  • tcp.flags 顯示包含TCP標誌的封包。
  • tcp.flags.syn == 0x02     顯示包含TCP SYN標誌的封包

 

8.包內容過濾

等等還有很多,再詳細的我們百度,用到哪個查哪個,一口吃不了個胖子,學linux一定要適可而止,每天知識點內容都太多了。

 

注意我們的抓取過程,在windows下運行wirshark,抓取本地虛擬機與遠程linux通訊的包的過程。

如果是本地的虛擬機內通訊沒經過網卡,我們windows下肯定是抓不到包。

 

 

二. 詳細講解各個層級的包頭

回故一下這是我們網絡中的封包和拆包的過程。從這個過程中,我們可以看到要增加很多的包頭,類似於我們快遞,每傳遞到一個地,要加一個地址一樣。雖然圖中寫的是以太網頭啊,ip頭啊,說的簡單,其實每個頭部內部又有很多的字節和很多的含義來溝通,下面我們就分別進行這些頭部內部的一個說明。

 

TCP/IP 協議網絡封包格式:

2.1  以太網頭格式(14字節)

目的地址和源地址都是MAC地址。

 

類型:TCP,UDP http等。

 

2.2 IP頭(20字節)

TOS:包括優先級字段,最小時延,最大吞吐量,最高可靠性和最小費用,其實說白了就是在網絡擁堵的時候,它決定傳誰。(給你的服務是vip,還是普通用戶)

 

標識字段:標識字段唯一地標識主機發送的每一份數據報。通常每發送一份報文它的值就會加1(處理大數據包時,用於拆包,接收機通過這些標識進行重組)

這個過程挺複雜也挺有意思的可以詳細的分析下,並且這個概念也經常出題,問IP頭中標識字段的作用。

 

生存時間:T T L(time-to-live)生存時間字段設置了數據報可以經過的最多路由器數。

 

2.3 TCP頭(20字節)

網絡傳輸層中,TCP是面向連接、可靠的、字節流傳輸。

端口號:作用就是我從哪裏來,又要到哪裏去。

32位序號:一次TCP通信(從TCP連接建立到斷開)過程中某一個傳輸方向上的字節流的每個字節的編號。

32位確認號:用作對另一方發送來的TCP報文段的響應。其值是收到的TCP報文段的序號值加1。

4位頭部長度:標識該TCP頭部有多少個32bit字(4字節)。

6位標誌位:

  • URG標誌:緊急指針(urgent pointer)是否有效。
  • ACK標誌:確認號是否有效。我們稱攜帶ACK標識的TCP報文段爲確認報文段。
  • PSH標誌:提示接收端應用程序應該立即從TCP接收緩衝區中讀走數據,爲接收後續數據騰出空間(如果應用程序不將
  • 接收到的數據讀走,它們就會一直停留 在TCP接收緩衝區中)。
  • RST標誌:要求對方重新建立連接。我們稱攜帶RST標誌的TCP報文段爲復位報文段。
  • SYN標誌:請求建立一個連接。我們稱攜帶SYN標誌的TCP報文段爲同步報文段。
  • FIN標誌:通知對方本端要關閉連接了。我們稱攜帶FIN標誌的TCP報文段爲結束 報文段。

16位窗口大小:是TCP流量控制的一個手段。

16位校驗和:由發送端填充,接收端對TCP報文段執行CRC算法以檢驗 TCP報文段在傳輸過程中是否損壞。注意,這個校驗不僅包括TCP頭部,也包括數據部分。

TCP頭部選項:TCP頭部的最後一個選項字段(options)是可變長的可選信息。這部分最多包含40字節

 

這樣我們就知道了這些字節的含義,但是其實我還是不太明白他們到底是啥?通過這麼幾個字節作爲基礎實現了複雜的邏輯,確實還是非常不好理解的。下面我們會簡單的分析一下其中一些重要的原理,幫助我們加深一下理解。

 

2.4 UDP頭(8字節)

三. TCP內關鍵機制詳細分析

我們都說TCP是可靠傳輸,那麼它是怎麼做到可靠的呢?

TCP中主要是通過以下幾個特性保證了數據傳輸的可靠:

(1)序列號和確認應答信號

(2)超時重發控制

(3)連接管理

(4)滑動窗口控制

(5)流量控制

(6)擁塞控制

 

3.1.超時重發機制

其實在我們平時的開發中,想要保證數據可靠也經常用到類似的簡單的機制。

本地機A發送一包數據給目標機器B,此時A上設置一個超時時間。如果在超時時間內B沒有給A返回應答包,我們就認爲他沒收到,然後A將數據包重發。

其實在這個過程中有可能是B沒收到,也有可能B返回應答包了,因爲一些原因應答包丟失或者延時到達。A很任性,認爲反正我沒收到,就要不斷重發,使B不斷的收到重複包這個過程非常浪費資源。

 

爲了幫助B不接收重複的包,就引入了序列號的概念

序列號是按照順序給發送數據的每一個字節(8位字節)都標上號碼的編號。接收端查詢接收數據 TCP 首部中的序列號和數據的長度,將自己下一步應該接收的序列號作爲確認應答返送回去。通過序列號和確認應答號,TCP 能夠識別是否已經接收數據,又能夠判斷是否需要接收,從而實現可靠傳輸。

 

剛纔我們也提到了要設置一個超時重發時間,時間沒到就重發,但是這個特定的時間間隔我們怎麼得到呢?理想狀態肯定是這個時間段又能幹了活,還要保證這個時間理論最短。

 

TCP中每次發包時都會計算往返時間(RTT Round Trip Time)及其偏差(RTT波動的時間,也叫抖動)。將這個往返時間和偏差時間相加,重發超時的時間就是比這個總和要稍大一點的值。

同時網絡在重發的過程中數據也不會被無限、反覆地重發。達到一定重發次數之後,如果仍沒有任何確認應答返回,就會判斷爲網絡或對端主機發生了異常,強制關閉連接。並且通知應用通信異常強行終止。

 

3.2  連接管理:

TCP是面向連接的通信協議,面向連接是指在數據通信之前先做好通信兩端之間的準備工作。
因此,在數據通信之前,會通過TCP首部發送一個SYN包作爲建立連接和等待確認應答,如果對端發來確認應答ACK,則認爲可以進行通信,否則如果對端沒有發送正確的ACK應答,那麼就不會通信。另外通信完畢需要發送FIN包來關閉連接

這就是我們常常說的 三次握手建立連接 和四次揮手關閉連接

三次握手:

(1)第一次握手:Client將標誌位SYN置爲1,隨機產生一個值seq=J,並將該數據包發送給Server,Client進入SYN_SENT狀態,等待Server確認。

(2)第二次握手:Server收到數據包後由標誌位SYN=1知道Client請求建立連接,Server將標誌位SYN和ACK都置爲1,ack=J+1,隨機產生一個值seq=K,並將該數據包發送給Client以確認連接請求,Server進入SYN_RCVD狀態。

(3)第三次握手:Client收到確認後,檢查ack是否爲J+1,ACK是否爲1,如果正確則將標誌位ACK置爲1,ack=K+1,並將該數據包發送給Server,Server檢查ack是否爲K+1,ACK是否爲1,如果正確則連接建立成功,Client和Server進入ESTABLISHED狀態,完成三次握手,隨後Client與Server之間可以開始傳輸數據了。

 

四次揮手:

(1)第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN_WAIT_1狀態。

(2)第二次揮手:Server收到FIN後,發送一個ACK給Client,確認序號爲收到序號+1(與SYN相同,一個FIN佔用一個序號),Server進入CLOSE_WAIT狀態。

(3)第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態。

(4)第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀態,接着發送一個ACK給Server,確認序號爲收到序號+1,Server進入CLOSED狀態,完成四次揮手。

 

從上面我們可看出,有了可靠的建立連接過程(三次握手),及可靠的 斷開過程(4次揮手),然後在發送過程又有序列號的超時重發機制。頭,尾,身體都有了,好像我們的TCP機制學完了呢。其實我們還忽略了一個重要的東西就是我們的數據包。在傳輸大數據包的時候我們該怎麼辦,肯定是分包唄,但是一分包處理機制就更加複雜了。那麼每次傳輸的分包長度是多少呢?

 

3.3數據包的發送,滑動窗口機制(提高數據傳輸效率)

TCP是以段爲單位進行數據包的發送的在建立 TCP 連接的同時,也可以確定發送數據包的單位,我們也可以稱其爲“最大消息長度”(MSS,Max Segment Size),也就是一個段。最理想的情況是,最大消息長度正好是 IP 中不會被分片處理(上面IP頭中說的,數據包太大會被碎片化處理的最大數據長度。

TCP 在傳送大量數據時,是以 MSS 的大小將數據進行分割發送。進行重發時也是以 MSS 爲單位。

MSS 在三次握手的時候,在兩端主機之間被計算得出。兩端的主機在發出建立連接的請求時,會在 TCP 首部中寫入 MSS 選項,告訴對方自己的接口能夠適應的 MSS 的大小。然後會在兩者之間選擇一個較小的值投入使用。

但是分包之後,每發送一段數據就進行一次確認應答,那麼包的往返時間就會加長,那麼性能肯定就越低了。過程如

下圖所示:

然後就引入了窗口的機制,那他的實現原理是什麼?有點像單線程變成了多線程處理,發送一段數據後,不用一直等待,接着發下一段,一直到最大的窗口大小後在進行應答處理。(使用了大量的緩衝區對數據進行緩存,然後對多段同時進行應答確認)

窗口大小:無需等待確認應答ACK而繼續發送數據的最大值。

優化後如下圖:

以下是滑動窗口的示意圖:圖看不懂??不要緊。

假如我們設置的窗口大小是4000字節,1段是1000個字節也就是發送四包後纔對ACK進行處理。

 

正常情況:小A有四個包裹編號1,2,3,4,小A遞給小B 1號包裹,2號包裹,3號包裹,4號包裹。過程中不管小B和我說啥,我都聽不見,當我遞完4號包裹後,纔會騰出耳朵來聽小B和我說啥(因爲你之前和我約定好了要專心,每遞完4包再聽我說話),此時聽見小B說,給我第5個包裹,那麼我就認爲你的前4個包裹都收到了,開始第5個包裹的傳遞,這樣當然是極好的。

異常情況:假如傳遞過程中出現了問題,小B沒收到2號包裹,就會告訴小A,我要2號包裹,然而小A聽不見啊,接着給第3個包裹,小B看到3號包裹後大怒,傻叉我要的是2號包裹,但是小A還是聽不見啊,又發了4號,小B一看竟然還不是2號包裹,我不要。告訴小A我就要2號包裹。此時小A發完四個包裹,終於能聽見聲音了,發現小B說給我第2個包裹,小A才意識到,我擦,2,3,4都丟了,只能返回到2的位置,將2,3,4,按順序重新給小B發一遍。

注:你會發現你設置的這個窗口類似於設置個緩衝區,只要人家沒確認收到,你就要隨時準備從緩存的指定位置讀取出來給人家重傳,收到了之後才能開始向下滑動,清理之前的數據緩存。以此類推可靠的完成所有數據包的傳輸。

 

如果我們的窗口大小設置的比較大,其中一包丟失了,別人都給你喊了100次了,你還一直給別人發不想要的也不行啊,於是又優化了機制。

高速重發控制:在滑動窗口比較大的情況下,同一個序列號的確認應答將會被重複不斷地返回。而發送端主機如果 連續 3 次 接收到同一個確認應答包,就會將其對應的數據重發,這種機制比之前提到的“超時重發”更加高效,所以被稱之爲“高速重發控制”(喊你三次發錯了,不糾正我就給你一棒子,我纔不管之前的約定的是啥呢)

每個頭的組成和含義我們都明確了,此時通過工具抓出一個完整的包,我們就可以對着含義進行理解了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章