網路程式設計雜談之TCP協議

2022-01-22 07:39:34 字數 2713 閱讀 1980

tcp協議屬於網路分層中的傳輸層,傳輸層作用的就是建立埠與埠的通訊,而其下一層網路層的主要作用是建立"主機到主機"的通訊,所以在我們日常進行網路程式設計時只要確定主機和埠,就能實現程式之間的資料交流,在unix系統中就把主機+埠,叫做"套接字"(socket),所以一般網路程式設計都是基於對於socket的操作來做的。

tcp協議其實是乙個非常複雜的協議,做過網路程式設計開發的都聽過一句話『』tcp本身是一種可靠的協議」,但正是為了保證可靠性,tcp 內部使用了如各種重傳與控制演算法,所以 tcp 是乙個內部原理複雜,但是使用起來比較簡單的協議。

下面我們對tcp協議進行乙個基本的介紹,本文只是站在應用的角度上闡述,相比與真正的深入還是比較淺顯的。

首先主要看下tcp協議的頭格式

其中各字段的意義如下:

3、包序號(sequence number):32位的sn序列號標識了tcp報文中第乙個byte在對應方向的傳輸中對應的位元組序號,用來記錄網路包順序,解決傳輸中的亂序、重複問題,比如傳送端傳送的乙個tcp包淨荷(不包含tcp頭)為10byte,sn為5,則傳送端接著傳送的下乙個資料報的時候,sn應該設定為5+10=15。通過序列號,tcp接收端可以識別出重複接收到的tcp包,從而丟棄重複包,同時對於亂序資料報也可以依靠系列號進行重排序,進而對高層提供有序的資料流。另外如果接收的包中包含syn或fin標誌位,邏輯上也占用1個byte,應答號需加1。 

4、確認號(acknowledgement number):32位的ack標識了報文傳送端期望接收的位元組序列,如果設定了ack控制位,這個值表示乙個準備接收的包的序列碼,注意是準備接收的包,比如當前接收端接收到乙個淨荷為10byte的資料報,sn為5,則會回覆乙個確認收到的資料報,如果這個資料報之前的資料也都已經收到了,這個資料報中的ack number則設定為10+5=15,表示之前的資料都已經收到了,準備接受sn=15的資料報。

5、視窗(advertised-window):著名的滑動視窗(sliding window),用於tcp的流量控制。

6、狀態位(tcp-flag):包的型別,用於操作tcp的狀態機,其8位狀態分別表示如下含義

7、校驗位(checksum):16位tcp頭。傳送端基於資料內容計算乙個數值,接收端要與傳送端數值結果完全一樣,才能證明資料的有效性。接收端checksum校驗失敗的時候會直接丟掉這個資料報。checksum是根據偽頭+tcp頭+tcp資料三部分進行計算的。

8、緊急指標(urgent pointer):16位,指向後面是優先資料的位元組,在urg標誌設定了時才有效。如果urg標誌沒有被設定,緊急域作為填充。 

9、選項(option):長度不定,但長度必須以是32bits的整數倍。常見的選項包括mss、sack、timestamp等等。

關於tcp的狀態機理解我們從幾張經典的示意圖開始

tcp狀態轉換圖

tcp三次握手、四次揮手時序圖

了解了以上的內容,下面我們就結合實際報文資料,對tcp鏈結三次握手,資料傳輸,斷開四次揮手,進行乙個簡單的跟蹤驗證;

1、三次握手

建立鏈結的三次握手的作用主要是初始化sequence number 的初始值,同時把這個值通過synchronize sequence numbers(syn包)告知對端。

通過wireshark可以捕獲到三次握手的報文

握手流程:

2、資料傳輸

通過wireshark,我們可以看下tcp傳輸中一包資料的組成,對照前面的協議組成,可以看到這裡我們傳送的是0x11,0x11兩個位元組的資料

可以看到接收一段回覆的確認包裡ack從1變成了3,為保證資料的順序性與可靠性,tcp是有一整套的機制來控制的,如大家熟悉的滑動視窗、超時重傳等;

這裡有乙個需要注意的細節,這裡ack確認號的真實值其實是從0xffeb49ed 變為 0xffed49ef的,這是由於當某個主機開啟乙個tcp會話時,他的初始序列號與確認號是隨機的,可能是0和4,294,967,295之間的任意值,在wireshark裡顯示的都是相對序列號/確認號,而不是實際序列號/確認號,相對序列號/確認號是和tcp會話的初始序列號相關聯的。這裡wireshark為方便大家跟蹤檢視顯示的是相對值,因為比起真實序列號/確認號,跟蹤更小的相對序列號/確認號會相對容易一些。

3、四次揮手

斷開鏈結的四次揮手的作用主要是**資源,停止資料傳輸。由於tcp是全雙工的,需要client與server兩端分別斷開各自的通向對方的通道。

通過wireshark可以捕獲到四次揮手的報文

揮手流程:

四次揮手的流程中,sever端在接收到client端的斷開要求後,ack確認包與fin包是否可以合併為乙個包來傳送,也就是四次揮手是否可能變成三次揮手,答案是可能的,但由於tcp是全雙工的,server端與client端資料傳輸的終止在時序上是獨立且可能相隔較長時間,那麼一般情況下乙個完整的斷開鏈結操作都是需要四次揮手來完成的。

到這裡針對tcp協議,以及鏈結->傳輸->斷開鏈結流程的基本介紹與說明就結束了,後續針對網路程式設計這一塊我會接著寫幾篇文章,一是對自己工作中涉及到一些網路程式設計的內容進行梳理與總結,另一方面希望能從下至上的加強自己對網路程式設計這塊認知的深度,也希望對大家能有所幫助,其中如有不足與不正確的地方還望指出與海涵。

雜談網路協議之TCP和HTTPS

先來說說協議可靠性,比如兩人接通 後先要寒暄幾句,一方面出於尊重,更主要目的是確認身份嘛,防止聊了半天,發現聊錯物件了哈。一樣的道理,兩台機器想要通訊互傳資料之前,先要建立連線,連線過程大致描述為 a傳送seq a給b,b傳送ack a 1,seq b給a,a傳送ack b 1給b,連線建立完成。連...

網路程式設計(TCP協議)

tcp協議,傳輸控制協議 英語 transmission control protocol,縮寫為 tcp 是一種面向連線的 可靠的 基於位元組流的傳輸層通訊協議,由ietf的rfc 793定義。tcp通訊需要經過建立連線 資料傳送 終止連線三個步驟。tcp通訊模型中,在通訊開始之前,一定要先建立相...

網路協議之TCP

為了實現計算機的通訊,我們為計算機定義了一系列的通訊規則,這些規則就是協議.資料格式封裝 傳輸 將複雜的流程分解為幾個功能相對單一的子程序。osi是乙個理想的模型,因此一般網路系統只涉及其中的幾層,很少有系統能夠具有所有的7層,並完全遵循它的規定。在7層模型中,每一層都提供乙個特殊的網路功能。從網路...