1. 程式人生 > >TCP/IP系列——TCP連線(1)

TCP/IP系列——TCP連線(1)

本文件不對TCP做詳細說明,這裡只是為說明HTTP的效能做相應的TCP鋪墊

一、TCP Format

Source Port & Destination Port 源埠號:用來指明發送應用程序; 目的埠號:用來指明接收方的應用程序。 Sequence Number 序列號。 該位元組表示本報文段所傳送的資料的第一個位元組的序號。TCP是面向位元組流的,在一個TCP連線中傳送的位元組流中的每一個位元組都按順序編號。整個要傳送的位元組流的起始序號必須在連線建立時設定。例如,某一報文段的序列號Sequence Number=201,攜帶100位元組的資料,則表明最後一個位元組的序號為300,下一個報文段的序列號得從301開始。 這個序列號是一個32位的無符號數,到達2^32-1後再迴圈回0開始。 Acknowledgment Number

確認號。 該位元組表示期望收到對方下一個報文段的第一個資料位元組的序號。例如,B正確收到了A發過來的一個報文段,序列號為201,資料長度為200位元組。則B回覆A的確認號則為Acknowledgement Number=401。 確認號的範圍是2^32-1,因此可以對4GB的資料進行編號,一般情況下,當序號需要重複使用時,舊序號的資料早已通過網路到達終點了。 ACK 確認 (ACKnowledgment)。 可攜帶資料。 僅當ACK=1時,確認號(Acknowledgement Number)才有效。TCP固定,在連線建立之後,所有傳送的報文段的ACK都必須置為1。 SYN 同步(SYNchronization)。 (TCP的SYN段也能夠承載應用資料。由於伯克利的套接字API不支援這種方式,因此它也很少為人所用。)->(源自TCP/IP卷1),待考證。 在連線時對序列號進行同步。當建立新連線時,SYN值被置為1。 當SYN=1,ACK=0,則表明這是一個連線請求報文段,因為連線建立之後的所有報文段的ACK都被置1。此時,若同意建立連線,則響應的報文段中使SYN=1,ACK=1。 SYN=1表示這是一個連線請求或連線接受報文。 FIN
終止。 用來釋放連線。FIN=1表示此報文段的傳送方的資料已經發送完畢,並要求釋放傳輸連線。 Options 選項。 當沒有選項時,TCP的首部長度為20位元組。

二、Three way handshake

在這裡插入圖片描述 Figure 2 3 A normal TCP connection establishment RFC 793: 在這裡插入圖片描述 《計算機網路(第7版)》 在這裡插入圖片描述 鑑於以上說明,所以這裡不作中文翻譯。 如Figure 2 3所示,連線建立的步驟如下(關於ISN參見ISN小節): B的TCP伺服器程序先建立傳輸控制塊TCB,準備接收客戶程序的連線請求。然後伺服器程序就處於LISTEN狀態,等待客戶程序的連線; 1. 主動開啟者(通常稱為客戶端)

:(1/3) 建立TCB,然後傳送一個TCP連線請求報文段,報文段中主要包括如下欄位: 目的埠號:指明通訊的程序; 序列號Seq=ISN©; SYN=1; 通常,客戶端還會藉此傳送一個或多個Options。 TCP客戶程序進入SYN-SENT(同步已傳送)狀態 2. 伺服器端(2/3) 若同意連線,則回一個TCP報文段,報文段中主要包括如下欄位: SYN=1; ACK=1; 序列號:Seq=ISN(s); 確認號:ack=ISN©+1; TCP客戶程序進入SYN-REVD(同步收到)狀態 3. 客戶程序A收到服務程序B的確認後,還要向B給出確認(3/3) TCP報文段主要包括如下欄位: ACK=1; 序列號:Seq=ISN©+1 確認號:ack=ISN(s)+1;

為何客戶程序A最後還要傳送一次確認? 為了防止已失效的連線請求報文段突然又傳送到B,因而產生錯誤。

ISN

ISN的值不是這個數字不是0和1,而是另一個數字,經常是隨機選擇的,稱為初始序列號(Initial SequenceNumber, ISN)。ISN不是0和1,是因為這是一種安全措施。[RFC793]指出初始序列號可被視為一個32位的計數器。該計數器的數值每4微秒加10。此舉的目的在於為一個連線的報文段安排序列號,以防止出現與其他連線的序列號重疊的情況。 當一個連線開啟時,任何擁有合適的IP地址、埠號、符合邏輯的序列號(即在視窗中)以及正確校驗和的報文段都將被對方接收。 如果連線由於某個報文段的長時間延遲而被關閉,然後又以相同的4元組被重新開啟,那麼可以相信延遲的報文段又會被視為有效資料重新進人新連線的資料流中。 解決方案:通過採取一些步驟來避免這種連線例項間的序列號重疊問題。現代系統通常採用半隨機的方法選擇初始序列號;Linux系統採用基於時鐘的方案選擇初始序列號,並且針對每一個連線為時鐘設定隨機的偏移量。隨機偏移量是在連線標識(即4元組)的基礎上利用加密雜湊函式得到的。雜湊函式的輸人每隔5分鐘就會改變一次。在32位的初始序列號中,最高的8位是一個保密的序列號,而剩餘的備位則由雜湊函式生成。但是這也只能降低風險,一個對資料完整性有較高要求的應用程式也可以在應用層利用CRC或校驗和保證所需資料在傳輸過程中沒有出現任何錯誤,這種方式已普遍用於大檔案的傳輸。 一個TCP報文段只有同時具備連線的4元組與當前活動視窗的序列號,才會在通訊過程中被對方認為是正確的。然而,如果知道序列號、 IP地址以及埠號,那麼任何人都能偽造出一個TCP報文段,從而打斷TCP的正常連線[RFC5961]。 解決方案:方案一:使初始序列號(或者臨時埠號)變得相對難以被猜出;方案二:加密。 綜上描述可知,在建立連線前通訊雙方選擇ISN的重要性。