TCP串連的建立和終止- -
編寫:Leaf Zhou
EMAIL:leaf_zhou_8@hotmail.com
可自由複製但禁止刪改
2005-04-19
TCP是英文Transport Control Protocol的縮寫。從字面理解,就是傳輸控制通訊協定。因此,TCP是一種控制協議,他本身不能用來傳輸資料,它需要通過網路層的IP協議來進行實際資料的傳輸。這也就是我們常常看到,TCP/IP和TCP/UDP總是同時出現的原因。因此,也可以理解為TCP是很多的不同的協議組成,實際上是一個協議組。提供可靠的主機到主機層資料轉送控制協議。這裡要先強調一下,傳輸控制通訊協定是OSI網路的第四層的叫法,TCP傳輸控制通訊協定是TCP/IP傳輸的6個基本協議的一種。TCP是一種可靠的連線導向的傳送服務。它在
一、TCP概述
TCP是英文Transport Control Protocol的縮寫。從字面理解,就是傳輸控制通訊協定。因此,TCP是一種控制協議,他本身不能用來傳輸資料,它需要通過網路層的IP協議來進行實際資料的傳輸。這也就是我們常常看到,TCP/IP和TCP/UDP總是同時出現的原因。因此,也可以理解為TCP是很多的不同的協議組成,實際上是一個協議組。提供可靠的主機到主機層資料轉送控制協議。這裡要先強調一下,傳輸控制通訊協定是OSI網路的第四層的叫法,TCP傳輸控制通訊協定是TCP/IP傳輸的6個基本協議的一種。TCP是一種可靠的連線導向的傳送服務。它在傳送資料時是分段進行的,主機交換資料必須先建立一個會話。它用位元流通訊,即資料被作為無結構的位元組流進行傳輸,沒有資料邊界。 通過每個TCP傳輸的欄位指定順序號,以獲得可靠性。是在OSI參考模型中的第四層,TCP是使用IP的網間互聯功能而提供可靠的資料轉送,IP不停的把報文放到網路上,而TCP是負責確信報文到達。在協同IP的操作中TCP負責:握手過程、報文管理、流量控制、錯誤偵測和處理(控制),可以根據一定的編號順序對非正常順序的報文給予從新排列順序。關於TCP的RFC文檔有RFC793、RFC791、RFC1700。
二、TCP串連的建立
建立一個TCP串連,需要下面的步驟:
(1)伺服器端通過listen來準備接受外來的串連,稱為被動開啟(passive open)。
(2)用戶端通過connect進行串連伺服器,稱為主動開啟(active open)。在這個操作中,用戶端需要發送一個同步資料報(SYN),用來通知伺服器端開始發送資料的初始序號。通常情況下,同步資料報不攜帶資料,它只包含一個IP頭部、一個TCP頭部和本次通訊所使用的TCP的選項。
(3)伺服器端必須對用戶端發來的同步資料報SYN進行確認,同時自己也要發送一個同步資料報(SYN),它包含用戶端發送資料的初始序號。伺服器端對在同一串連中發送的資料初始序號和對用戶端發送的確認資訊(ACK),都放在一個資料報中,一起發送給用戶端。
(4)用戶端也必鬚髮送確認伺服器端的同步資料報(SYN)。
由上面的步驟來看,建立一個TCP串連,至少需要伺服器端和用戶端進行三個分組資料的交換,因此,稱之為TCP的三路握手(three-way handshake)。
用戶端 伺服器端
connect() accept()
---> SYN S ----->
<--- SYN C,ACK S+1 <---
---> ACK C+1 ----->
第一次進行分組資料交換的過程中,分組資料中可能包含著本次通訊中可能的TCP選項。這些選項有:
(1)最大分組(MSS)選項。TCP發送的SYN中帶有這個選項,用來告訴對方它的最大分組資料的大小MSS(Maximum Segment Size),即它能接收的每個TCP分組資料中的最大資料量。這個選項可以通過TCP_MAXSEG套介面選項擷取與設定這個TCP選項。
(2)視窗大小選項。這是TCP能提供流量控制的主要手段。TCP串連的每一方都有固定大小的緩衝空間,TCP的接收端只允許另一端發送接收端緩衝區所能接納的資料。這將防止較快主機致使較慢主機的緩衝區溢位。TCP雙方能夠通知對方的最大視窗大小是64K(65535 bytes),因為TCP頭部相應的識別欄位值只用了16位來表示。每個套介面都有一個發送緩衝區和一個接收緩衝區,接收緩衝區被TCP和UDP用來將接收到的資料一直儲存到由應用進程來讀取。對於TCP,TCP通告另一端的視窗大小。 TCP套介面接收緩衝區不可能溢出,因為對方不允許發出超過所通告視窗大小的資料。 這就是TCP的流量控制,如果對方無視視窗大小而發出了超過視窗大小的資料,則接收方TCP將丟棄它;而對於UDP,當套介面接收緩衝區放不下接收到的資料報時,此資料報就被丟棄。UDP是沒有流量控制的,快的寄件者可以很容易地就淹沒慢的接收者,導致接收方的UDP丟棄資料報,使資料發生丟失。
(3)時間戳記選項。時間戳記選項使發送方在每個報文段中放置一個時間戳記值。接收方在確認中返回這個數值,從而允許發送方為每一個收到的ACK計算RTT。
三、TCP串連的終止
終止TCP串連
TCP用三個分組資料建立一個串連,但要終止一個串連則通常需要需要四個分組資料。過程如下:
(1)先調用close的進程,稱為主動關閉(active close)。這一端的TCP先發送一個FIN分組資料,告訴對方,資料發送完畢。
(2)接收到FIN分組資料的一端執行被動關閉(passive close),同時,發送對這個FIN的確認ACK分組資料給對方。確認序號為收到的序號加1。FIN分組資料的接收意味著在當前的串連上,再也不會收到額外的資料。
(3)接收到FIN分組資料的一端的應用進程,將調用close關閉自己的套介面,同時TCP 會發送一個FIN分組資料給另一端。
(4)收到這個FIN的分組資料,即執行主動關閉的一端對這個FIN分組資料進行確認。發回確認ACK分組資料,並將確認序號設定為收到序號加1
在這個過程中,執行被動關閉的一方可以把確認對方FIN分組資料的ACK分組資料和自己要發送的FIN分組資料可以放到一個分組資料中。TCP的串連終止的過程如下:
用戶端 伺服器端
close() close()
---> FIN S ----->
<--- ACK S+1 <---
<--- FIN C <---
---> FIN C+1 --->
四、TCP連的狀態
TCP的串連的建立和終止,基本上已經清楚了,那麼在這個過程中,是如何知道這個串連正處在什麼狀態呢?方法當然是有的,我們先運行如下命令,看看返回的結果:
[root@linux81 leaf]# netstat -an
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:139 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:23 0.0.0.0:* LISTEN
tcp 0 0 192.168.253.81:139 192.168.253.35:1201 ESTABLISHED
tcp 0 272 192.168.253.81:22 192.168.253.59:1776 ESTABLISHED
udp 0 0 192.168.253.81:137 0.0.0.0:*
udp 0 0 0.0.0.0:137 0.0.0.0:*
udp 0 0 192.168.253.81:138 0.0.0.0:*
udp 0 0 0.0.0.0:138 0.0.0.0:*
udp 0 0 127.0.0.1:36260 0.0.0.0:*
在上面的返回結果中,State一列,就是說明串連的目前狀態。
TCP的串連狀態有:
(01)CLOSED
(02)LISTEN 被動開啟
(03)SYN_RCVD
(04)SYN_SEND
(05)ESTABLISHED 資料傳送狀態
(06)CLOSE_WAIT
(07)LAST_ACK 被動關閉
(08)FIN_WAIT_1
(09)FIN_WAIT_2
(10)CLOSING
(11)TIME_WAIT
TCP串連狀態轉換如下所示:
+---------+ ---------/ active OPEN
| CLOSED | / -----------
+---------+<---------/ / create TCB
| ^ / / snd SYN
passive OPEN | | CLOSE / /
------------ | | ---------- / /
create TCB | | delete TCB / /
V | / /
+---------+ CLOSE | /
| LISTEN | ---------- | |
+---------+ delete TCB | |
rcv SYN | | SEND | |
----------- | | ------- | V
+---------+ snd SYN,ACK / / snd SYN +---------+
| |<----------------- ------------------>| |
| SYN | rcv SYN | SYN |
| RCVD |<-----------------------------------------------| SENT |
| | snd ACK | |
| |------------------ -------------------| |
+---------+ rcv ACK of SYN / / rcv SYN,ACK +---------+
| -------------- | | -----------
| x | | snd ACK
| V V
| CLOSE +---------+
| ------- | ESTAB |
| snd FIN +---------+
| CLOSE | | rcv FIN
V ------- | | -------
+---------+ snd FIN / / snd ACK +---------+
| FIN |<----------------- ------------------>| CLOSE |
| WAIT-1 |------------------ | WAIT |
+---------+ rcv FIN / +---------+
| rcv ACK of FIN ------- | CLOSE |
| -------------- snd ACK | ------- |
V x V snd FIN V
+---------+ +---------+ +---------+
|FINWAIT-2| | CLOSING | | LAST-ACK|
+---------+ +---------+ +---------+
| rcv ACK of FIN | rcv ACK of FIN |
| rcv FIN -------------- | Timeout=2MSL -------------- |
| ------- x V ------------ x V
/ snd ACK +---------+delete TCB +---------+
------------------------>|TIME WAIT|------------------>| CLOSED |
+---------+ +---------+
TCP Connection State Diagram
從上面的圖表中,可以做出如下總結:
伺服器端的正常狀態轉換過程如下:
CLOSED --> LISTEN --> SYN_RCVD --> ESTABLISHED --> CLOSE_WAIT --> LAST_ACK --> CLOSED
用戶端的正常狀態轉換過程如下:
CLOSED --> SYN_SENT --> ESTABLISHED --> FIN_WAIT_1 --> FIN_WAIT_2 --> TIME_WAIT --> CLOSED
從上面的串連狀態轉換中可以看出,從ESTABLISHED狀態的轉換有兩種,對於用戶端和伺服器端來說,是一樣的,即當收到FIN資料報之前,主動關閉,則轉換成FIN_WAIT_1;如果因為收到FIN資料報,而引起的被動關閉,則轉換成CLOSE_WAIT狀態。