簡介
本文我們將從 RFC 學習一下 RFC793 中描述的 TCP 協議. 這將區別於通常講解計算機網絡書籍中所描述的 TCP. 但他們必然是相統一的,不會互相沖突.
消息格式
毫無疑問,我們首先得描述一下 TCP 數據包的格式.
RFC 中規定的格式如下:
各字段的意義及其值:
這裏我們先簡要的介紹一下,後續詳細逐一描述每個字段的用途
- Source Port: 16bits. 標記 TCP 數據包的發送方發送該數據時使用的端口號
- Destination Port: 16bits. 標記 TCP 數據包的接收方接收該數據包所使用的端口號
- Sequence Number: 32bits. 表示當前 TCP 數據包中數據的第一個字節的的序列號. 有一個例外,噹噹前數據包時包含 SYN 標記時,當前包中的序列號代表 初始序列號(initial sequence number, ISN), 第一個字節的序列號將是 ISN + 1
- Acknowlegment Number: 32bits. 當 ACK 標記被設置之後,這個字段表示接受方期待收到的下一個數據段的 sequence number. (當TCP連接建立之後,這個字段總是會被包含)
- Data Offset: 4bits. 標識當前TCP數據包所包含的實際有效數據的偏移. 單位是 32bit,也就是 4 byte.
- Reserved: 6 bits
- Control Bits: 6bits.
- URG: Urgent Pointer field significant
- ACK: Acknowldgment field significant
- PSH: Push Function
- RST: Reset the connection
- SYN: Synchronize sequence numbers
- FIN: No more data from sender
- Window: 16bits. 表示當前接收方能接受的數據的數量(以當前 TCP 頭中的 Acknowlegment Number 爲基準 )
- Checksum: 16bits.
- Urgent Pointer: 16bits.
- Options: 可變長度.
- Padding: 可變長度. 作用是將 TCP 數據包長度擴充爲 32 的整數倍. padding 的值總是 0 到多個 0.
術語
在我們詳細的描述 TCP 行爲之前,我們需要先引入一些術語,這樣會使後續的描述更直白易懂.
維護一個 TCP 連接需要記錄一系列的連接狀態, 我們假定有一個數據結構叫做 TCB(Transmission Control Block). 這個結構中需要存儲以下連接相關的信息: Local/Remote socket number,安全性,優先級, 發送/接收方的 buffer 指針, 重發隊列的指針和當前 TCP 段信息. 此外還有許多額外的信息.
Send Sequence Variables
SND.UNA - send unacknowledged
SND.NXT - send next
SND.WND - send window
SND.UP - send urgent pointer
SND.WL1 - segment sequence number used for last windows update
SND.WL2 - segment acknowldgment number used for last window update
ISS - initial send sequence number
這裏用一張圖來描述一下發送序列.
Send Sequence Space
- 序列號小於 SND.UNA 的數據的狀態爲: 已發送且收到了對應的 ACK. 對應圖中 段1
- 序列號處於 (SND.UNA, SND.NEXT) 的數據的狀態爲: 已發送但是還未收到對應的 ACK. 對應圖中 段2
- 序列號處於 [SND.NEXT, SND.UNA + SND.WND) 的數據的狀態: 表示可用的序列號,接下來發送的數據將被賦予這些序列號. 對應圖中 段3
- 序列號大於 SND.UNA + SND.WND 在當前狀態下是不可用的. 對應圖中 段4
- 段2 標記了當前的發送窗口
Receive Sequence Variables
RCV.NXT - receive next
RCV.WND - receive window
IRS - initial receive sequence nubmer
這裏用一張圖來描述一下接收序列.
Receive Sequence Space
- 序列號小於 RCV.NXT 的數據的狀態爲: 已接收且發送了對應的 ACK. 對應圖中 段1
- 序列號處於 (RCV.NXT,RCV.NXT + RCV.WND) 的序列號爲期待接收到的數據的序列號. 對應圖中 段2
- 序列號大於 RCV.NXT + RCV.WND 的序列號在當前狀態下是不可用的. 對應圖中 段3
- 段 2 標記了當前的接收窗口
Current Segment Variable
SEG.SEQ - segment sequence number
SEG.ACK - segment acknowldgment number
SEG.LEN - segment length
SGE.WND - segment window
SEG.UP - segment urgent pointer
SEG.PRC - segment precedence value
State
在一個 TCP 連接的生命週期中會在不同的狀態之間變化. 這些狀態分別是:
- LISTEN: 表示在等待一個遠程連接請求
- SYN-SENT: 表示請求連接的請求已經發送,在等待對方的連接請求
- SYN-RECEIVED: 表示發送了連接請求且收到了對方的連接請求,正在等待確認建立連接的 ACK
- ESTABLISHED: 表示一個 TCP 連接已經建立, 可以在當前連接上接收發送數據
- FIN-WAIT-1: 表示在等待對方發送關閉連接請求,或者等待對方發送對應於自己剛剛發送的關閉連接請求的 ACK.
- FIN-WAIT-2: 表示在等待對方發送關閉連接請求
- CLOSE-WAIT: 表示在等待本地用戶的關閉連接請求
- CLSING: 表示在等待對方發送關閉連接請求ACK.
- LAST-ACK: 表示在等待對方發送對應於自己剛剛發送的關閉連接請求的 ACK.
- TIME-WAIT: 表示正在等待一段時間以確保對方收到我們發送的關閉連接請求的 ACK
- CLOSED: 表示當前連接已經完全關閉了
用一張圖描述這些這些狀態之間的切換. 注意,這只是一張簡圖,並未涵蓋整個協議中規定的狀態變換.
作爲 TCP 協議的第一篇文章,此篇我們先簡單介紹 後邊文章中需要的基礎概念,後續使用專門文章來描述序列號,建立連接,關閉連接,發送/接收數據等流程.
END!