如下爲TCP在IP數據報中的封裝算法
一個IP地址和端口的組合稱爲「套接字」或「端點」。tcp
因此IP協議中的源IP地址和目的地址加密
和TCP協議中的源端口和目的端口,3d
組成了「一對」套接字(發送端的套接字和接收端的套接字)。指針
每個「TCP報文段中的第一個字節」都會被賦予一個序列號。blog
序列號是個32位數,到達2^32-1後會再回到0.隊列
也稱ACK號或ACK字段。ip
確認號包含的值爲:「確認號的發送方」但願接收的下一個序列號。(即最後接收成功的序列號+1)請求
該字段表示TCP頭部的長度,以32位字爲單位。程序
因爲「選項字段」大小是可變的,因此「頭部長度」字段是必須的。
TCP頭部長度最大爲60字節,若是沒有選項字段,則爲20個字節。
如下各個標識表示了「該TCP報文段」是幹什麼的。
如:
SYN和ACK可能同時爲1,它表示的就是創建鏈接以後的響應。
單個的一個SYN,它表示的只是創建鏈接。
一、CWR:擁塞窗口減(發送方下降它的發送速率)。
二、ECE:ECN回顯(發送方接收到了一個更早的擁塞通告)
三、URG:緊急(緊急指針字段有效,不多用)
四、ACK:確認(確認號字段有效,鏈接創建後通常都是啓用狀態)
五、PSH:推送(幾乎沒被用到)
六、RST:重置鏈接(鏈接取消)
七、SYN:表示創建鏈接
八、FIN:該報文的發送方已經結束向對方發送數據
在TCP協議裏,一個分組從發送端發送到接收端後,接收端應該返回一個ACK號。
如以前所說,每個分組都是從「序列號」開始的,咱們定一個術語「窗口」,來表示:已發送的分組們,但這些分組還未返回確認號(ACK號)。
窗口中的分組數量稱之爲:「窗口大小」。
下圖爲發送方的窗口以及其餘分組隊列:
如圖所示,若是發送方下一步接收到了序列號爲4的分組的「ACK」,則「窗口向右滑動一個分組」,意味着分組4能夠釋放了,分組7能夠發送了。這種行爲稱之爲:「窗口滑動協議」。
該校驗算法與IP、ICMP、UDP校驗算法一致,其覆蓋了TCP頭部和數據中的一些字段。
只有在有URG字段時纔有效。該指針是一個加到「序列號字段」上的正偏移,以產生「緊急數據」的最後一個字節的序列號。
最多見的選項字段爲:「最大段大小」字段,稱爲MSS。
鏈接的每一個端點(套接字)通常在它發送的第一個報文段上指定該選項。
下面咱們會詳講這些額外「選項」。
一個TCP鏈接由一個4元組構成,它們分別是發送端ip地址,發送端tcp端口,接收端ip地址,接收端tcp端口。也就是說,tcp鏈接由一對套接字構成。
TCP鏈接一般分爲3個階段:啓動、數據傳輸(鏈接已創建)、退出(鏈接關閉)。
過程以下圖:
第一次握手:(問服務端「你能不能聽見我說話?」)
客戶端主動發送一個TCP報文段,
裏面SYN字段設爲1(表示創建鏈接,即「詢問」),且包含了該報文段的初始「序列號」(記爲ISN(c),該初始序列號是隨機產生的)。
一般,客戶端還會藉此發送多個「選項」。
第二次握手:(回答客戶端說「能聽見你說話」,但問客戶端「你能不能聽見我說話?」)
服務端也發送本身的TCP報文段做爲響應,
裏面的SYN和ACK字段設爲1(表示創建鏈接以後的響應,即詢問+響應)。
該報文段的序列號爲它本身的初始「序列號」(記爲ISN(c),該初始序列號是隨機產生的)。
該報文段還包含「確認號」,爲「第一次握手時得到的ISN(c)+1」。(以前講過,確認號表示:「確認號的發送方但願接收的下一個序列號」。即接收成功的序列號+1)
第三次握手:(回答服務端說「能聽見你說話」)
客戶端響應服務端,
裏面的ACK字段爲1(即響應)。
該報文段的序列號爲ISN(c)+1(恰好與第二次握手的確認號相呼應)。
確認號爲ISN(s)+1(即第二次握手中的序列號+1)
鏈接的雙方都能關閉鏈接,但傳統狀況下是客戶端負責發起關閉鏈接。
一、鏈接的主動關閉者(圖中爲客戶端)發送一個FIN=1(表示已經結束向對方發送數據)和ACK=1(表示接收到了以前發送過來的最後一個數據)的報文段。
二、被動關閉者,先發個ACK報文段,表示:已經接收到剛剛的報文了。再發個ACK+FIN報文字段,此時被動關閉者的身份又轉換成了主動關閉者,表示它也要關閉了。
三、最後,客戶端發送一個ACK報文表示知道了。
所謂半關閉就是:
關閉的發起端發送了「要求關閉的報文」,(客戶端發送:FIN+ACK)
接收端返回響應表示接收到了(服務端發送:ACK)
但被動關閉方可能數據沒傳完,因此繼續傳了不少數據給發起端,
而後發起端確認接收到這些數據了,
而後被動關閉方再發送「關閉報文」(服務端發送:FIN(此時沒有ACK了,由於ACK的做用是表示「接收到了你發來的報文」,而客戶端已經沒有發來報文了))
客戶端發個響應表示知道了(客戶端發送:ACK),TCP鏈接關閉。
(即:鏈接的一方關閉,另外一方仍然傳輸數據直到它關閉爲止)
所謂同時打開關閉就是:
通訊雙方在接收到來自對方的SYN報文段(SYN=1表示創建鏈接)以前,雙方都要先給對方發送一個SYN報文。
而後雙方再響應各自收到的報文(即雙方都再發送SYN+ACK報文段)。
以前說過了,TCP頭部包含了多個可選的「選項」字段。
下面詳細介紹幾個比較經常使用的選項:
最大段大小是指TCP協議所能容許的從對方接收到的最大報文段(即通訊對方所能使用的最大報文段)。
當創建一條TCP鏈接時,通訊的每一方都應在SYN報文段的MSS選項中說明本身所容許的「最大報文段」。
最大段的默認大小爲:536字節。
在沒有加這個選項以前,假設發送端按序發送給接收端5個分組報文,
客戶端發送第1個,接收端返回ACK表示確認。
客戶端發送第2個,中途出了問題無法送到。接收端返回響應表示剛剛的數據2報文錯誤。
客戶端發送第3個,(客戶端不能響應,由於沒正確的接收到數據2)
客戶端發送第4個,(客戶端不能響應,由於沒正確的接收到數據2)
此時客戶端收到報文2的錯誤響應。
客戶端再發送第2個,接收端返回ACK表示確認。
客戶端再發送第3個,接收端返回ACK表示確認。
客戶端再發送第4個,接收端返回ACK表示確認。
······
由此可看出,客戶端重複的發送了2之後的報文。
若是「TCP接收方」能提供「選擇確認選項(SACK)」,
那麼服務端即便沒接收到數據2,也依然會正常接收數據2之後的報文。
用戶超時數值指明瞭TCP發送者願意等待ACK確認的時間。
該選項使用一種散列加密算法以及鏈接雙方共同維護一個祕密值來認證每個報文段。
TCP認證選項不只提供各類加密算法,還使用帶內信令來確認祕鑰是否改變。
以前提到了TCP在不一樣的階段會發送各類各樣的報文段,而這些決定TCP應該作什麼的規則,實際上是由TCP所屬的「狀態」決定的。
而TCP的狀態會在各類觸發條件下改變。
咱們仍是來看一下TCP的鏈接與關閉:
ESTABLISHED是通訊雙方雙向傳輸數據的狀態。
FIN_WAIT_1,FIN_WAIT_2,TIME_WAIT稱做:「主動關閉」狀態。
它們表示當本地應用程序發起一個請求時會進入的狀態集合。
CLOSE_WAIT,LAST_WAIT表示「被動關閉」,
這些狀態與等待一個節點確認一個FIN報文段相關。