傳輸控制協議,即TCP,是一種面向連接的傳輸協議,爲兩端的應用程序提供可靠的端到端數據流傳輸服務,它完全不同於
無連接的、提供不可靠數據傳輸服務的UDP協議。
下圖描述了各TCP函數與其他內核函數之間的關係,帶陰影的橢圓分別表示我們將要討論的9個主要的TCP函數。
1.TCP的protosw結構
下圖列出了TCPprotosw結構的成員變量,它定義了TCP協議與系統內其他協議之間的交互接口。
2.TCP的首部
tcphdr結構定義了tcp首部。下圖給出了tcphdr結構的定義和TCP首部。
大多數的RFC文檔中,相關書籍(包含卷1)和接下來要討論的TCP實現代碼,都把th_urp稱爲緊急指針。更準確的名稱
應該是緊急數據偏移量。因爲這個字段給出的16bit無符號整數值,與th_seg序號字段相加後,得到發送的緊急數據最後
一個八位組的32bit序號。
th_flags成員變量包含6個碼元標誌比特,通過下圖中定義的名稱讀寫。
下圖給出的ipovly結構定義了20字節長度的IP首部。通過前面的章節的討論可知,儘管長度相同(20字節),但這個結構並
不是一個真正的IP首部。
3.TCP的控制塊
除了標準的Internet PCB外,TCP還有自己專用的控制塊,tcpcb結構,而udp則不需要專用控制塊,它的全部控制信息都
已包含在Internet PCB中。
TCP控制塊較大,需佔用140個字節,下圖給出了TCP控制塊的定義。
下圖給出了t_flags變量的可選值。
4.TCP的狀態遷移圖
TCP協議根據連接上到達報文的不同類型,採取相應動作,協議規程可抽象爲下圖所示的有限狀態變遷圖。圖中的各種狀態
變遷組成了TCP有限狀態機。儘管TCP協議允許從LISTEN狀態直接變遷到SYN_SENT狀態,但使用socket api編程時這種
變遷不可實現。(調用listen後不可以調用connect)
TCP控制塊的成員變量t_state保存一個連接的當前狀態。取值如下:
圖中還定義了tcp_outflags數組,保存了處於對應連接狀態時tcp_output將使用的輸出標誌。
下圖爲TCP狀態遷移圖:
5.TCP的序號
TCP連接上傳輸的每個數據字節,以及SYN、FIN等控制報文都被賦予一個32bit的序號。TCP首部的序號字段填充了報文段
第一個數據字節的32bit的序號,確認號字段填充了發送方希望接收的下一個序號。確認已正確接收了所有序號小於等於確認
號減1的數據字節。換言之,確認號是ACK發送方等待接收的下一序號。只有當序號首部的ACK標誌置位時,確認序號纔有效。
除了在主動打開首次發送SYN時或在某些RST報文段中,ACK標誌總是被置位的。
1.序號取模運算
TCP必須處理一個問題是序號來自有限的32位取值空間:0~2^32-1,如果某個TCP連接傳輸的數據量超過2^32字節,序號從
2^32-1迴繞到0,將出現重複序號。
即使傳輸數據量小於2^32字節,仍可能遇到相同的問題,因爲連接的初始序號並不一定從0開始。各數據流方向上的初始序號
可以是0~2^32-1之間的任意值。
在tcp.h中,TCP序號定義爲unsigned long,下圖定了4個用於序號比較的宏。
下面舉例說明TCP序號的操作方式,假定序號只有3bit,0~7。下圖列出了8個序號和相應的二進制補碼。(爲求無符號數的
二進制補碼,將二進制中的所有0變成1,所有1變成0,再加上1),給出補碼形式,是因爲a-b = a+(b的補碼)
最後三欄分別是0-x,1-x和2-x的運算結果,其中最前面爲0表示正數,爲1表示負數。上面的1-x的結果表示:1大於0,1,6,7,
小於2,3,4,5.