Socket網絡編程之TCP

如果要用一句話總結TCP是什麼,我想應該是:TCP是因特網運輸層的面向連接的、可靠的、基於字節流的、全雙工的運輸協議

TCP運輸層協議服務

在分析TCP服務之前需要說明TCP在網絡協議分層中處於哪個層次,下圖是TCP/IP協議族的四個層次:

TCP和UDP都使用相同的網絡層(IP),但是TCP嚮應用層提供了和UDP完全不同的服務,TCP提供了一種面向連接的、可靠的字節流服務。

TCP的面向連接意味着使用TCP的兩個應用在交換數據之前必須建立一個TCP連接。這就類似於平時我們使用微信語音或者視頻聊天時,必須先發起語音申請,等待對方接通之後,然後才能聊天。所以在TCP連接中只有兩方彼此通信,我們平時說的廣播和多播並不適用於TCP。

一旦建立起一個TCP連接,兩個進程之間就可以互相發送數據了,這裏模擬一下客戶進程向服務器進程發送數據的情況,如下圖:

從上圖可以看出,客戶端進程通過套接字(socket)傳遞數據流。套接字將數據傳入客戶端運行的TCP控制之後,TCP就會將數據引導到該鏈接的發送緩存中,發送緩存是在三次握手初期設置的緩存之一。當數據進入發送緩存之後,TCP就會不時的從發送緩存取出一塊數據,TCP應該在它方便的時候以報文段的形式發送數據。

最大報文段長度(MSS)

最大報文段長度通常根據最初確定的由本地發送主機發送的最大鏈路層幀長度來設置,最大鏈路層幀長度即所謂的最大傳輸單元(Maximum Transmission Unit)。MSS=MTU-20字節TCP報頭-20字節IP報頭。以太網和PPP鏈路層協議都具有100字節的最大傳輸單元,因此MSS的典型值爲:1500-20-20=1460字節。

TCP報文段結構

TCP報文段由首部字段和一個數據字段組成,如下圖所示:

如上圖所示,數據字段包含一塊應用數據,就如上段內容所說,MSS限制了報文段數據字段的最大長度。當TCP發送一個大文件時,TCP通常會將文件分爲MSS大小的若干塊。

首部包括源端口號和目的端口號,被用於多路複用/分解來自或送到上層應用的數據,TCP首部也包括校驗和字段。

UGR:緊急指針有效

ACK:確認序號有效

PSH:接收方應該儘快將這個報文段交給應用層

RST:重建連接

SYN:同步序號用來發起一個連接

FIN:發端完成發送任務

可以看到窗口大小隻有16位,也就是最大窗口大小是65535個字節(64KB),TCP的流量控制就是由連接兩端通過聲明的窗口大小來提供。

校驗和貫穿了整個TCP報文段,即TCP首部和TCP數據。校驗和是一個強制性的字段,一定是由發端計算和存儲,由接收端進行驗證。

TCP面向連接

我們知道TCP是面向連接的協議,那麼什麼是長連接?什麼是短連接?什麼是連接?

長連接就是當實現客戶端和服務端連接成功後可以連續地傳輸數據,這個過程中連接保持開啓的狀態,並且數據即使傳輸完畢連接也不會關閉。在socker通信中是指建立socket連接後,無論是否使用該連接,連接都保持連接的狀態。

短連接就是什麼時候需要傳輸數據就創建連接,當數據傳輸完畢,該連接也就不存在了。如果想再次傳輸數據,需要重新創建新的連接。

連接是在TCP/IP中,連接是客戶端和服務端確認彼此存在的過程,要實現這個過程,就需要客戶端和服務端創建連接,創建連接需要客戶端和服務端進行三次握手,只有握手成功之後,雙方纔能進行通信。

長連接的優缺點:

優點:

我們知道長連接建立之後,客戶端不需要再每次傳輸數據時創建連接,這樣就減少了握手確認時間,提高程序效率。

缺點:

在服務器端保存了多個socket對象,大量佔用服務器資源。

短連接的優缺點:

優點:

對應長連接的缺點,短連接不需要在服務器端保存多個socket對象,降低內存佔用率。

缺點:

缺點也是對應長連接的優點,在每次通信時都需要創建新連接,進行三次握手增加處理時間,降低程序使用率。

三次握手

三次握手顧名思義就是通過三次數據交換建立連接,具體實現如下圖所示:

通過三次握手確認的主要信息是約定好雙方後續通信需要的起始序列號、窗口縮放大小等信息。下面對三次握手做一個簡單的介紹。

  1. 發端通常是客戶,發送一個SYN段指出客戶打算連接的收端(服務器端)的端口,以及初始序列,這個SYN端爲之前介紹的報文段1。

  2. 收端作爲迴應,發出包含服務器的初始化序列SYN,同時將確認序號ACK設置爲客戶端請求時ISN加1以對客戶的SYN報文段進行確認,SYN佔用一個序列號。

  3. 類似於服務器確認客戶端SYN信息,客戶必須將確認序號設置爲服務器的ISN加1以對服務器的SYN報文段進行確認。

三次握手用我們日常生活中的例子來總結,類似於我們一次簡單的發快遞服務,流程如下:

  1. 在快遞平臺填寫基本信息,提交給物流公司(類似於三次握手第一次握手)。

  2. 快遞員打電話確認基本信息(類似於第二次握手)。

  3. 快遞員上門取件,確認信息(類似於第三次握手)。

其實各種技術源於生活,服務於生活,在學習時在生活中都能找到非常多的例子,這樣可以幫助記憶、理解。

TCP協議是可靠的

我們知道在網絡通信中,UDP協議是不可靠的,TCP是可靠的,那麼什麼機制保證了TCP協議的可靠性了,具體原因如下:

  • 應用數據分割。TCP在發送數據時會將應用數據分割成最合適發送的數據塊,所以應用程序產生的數據長度將保持不變。

  • 定時器。當TCP發出一條信息之後,就會啓動一個定時器,等待目的服務器確認收到該信息。如果目的服務器在定時器範圍內沒有確認反饋,就會重發這條信息。

  • 對每個報文段提供校驗和。在前面介紹TCP報文結構時就已經解釋過,校驗和是一個強制性字段。這是一個端到端的校驗和,目的就是爲了檢測數據在傳輸過程中的每一個變化細節。如果收到報文之後發現校驗和錯誤,TCP就會丟棄該報文並不確認,觸發TCP重發機制重發該信息。

  • 重新排序機制。TCP使用的網絡層是IP,IP數據報到達目的服務器可能會失序,因此會導致TCP報文的失序,所以TCP會將收到的報文重新排序之後再交給應用層。

  • 丟棄機制。IP數據報可能會重發,因此TCP接收端會丟棄重複的數據報。

  • 流量控制。在前面介紹過TCP的緩存空間,TCP的接收端只接受另一端發送接收緩存空間能容納的數據大小,這樣就防止了數據溢出。

通過上述所描述的機制,確保了一個進程從其接收緩存中讀出的數據流是無間隔無損壞非冗餘按序的數據流;即該接收端接收到的字節流和發送端發出的字節流是完全相同的。

TCP字節流服務

TCP是一種字節流協議,流的定義沒有固定的邊界,可以是二進制數據,也可以是ASCII字符或者其他類型數據。TCP對字節流的內容不做任何解釋,對字節流的解釋由TCP連接雙方的應用層負責。

發端和收段通過TCP連接交換字節流,TCP不在字節流中插入任何記錄標識信息,這就是TCP的字節流服務。

TCP全雙工服務

TCP提供的是全雙工服務,即連接兩端可以是這樣的形式:客戶端/接收端,接收端/客戶端,也就是說連接通信的雙方既可以接收數據,也可以發送數據。例如:一臺主機上的進程A和另一臺主機上的進程B存在TCP連接,那麼應用層數據可以從A流向B,也可以從B流向A。

TCP提供的服務總是點對點的連接,即是單個發送方和單個接收方的連接,絕對不會存在多播的情況發生。

總結

TCP 是一個可靠的(reliable)、面向連接的(connection-oriented)、基於字節流(byte-stream)、全雙工(full-duplex)的協議。

留一個思考題:對於一次電話交談,哪一方是主動打開?哪一方是被動打開?是否允許同時打開?是否允許同時關閉?

實時博文,可以關注公衆號《編程之藝術》

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