1. 程式人生 > >TCP協議

TCP協議

tcp

TCP(Transmission Control Protocol )傳輸控制協議,是目前傳輸層應用最廣泛的協議,當然這跟它的特性息息相關。技術分享

一、它的主要特性有:

1、可靠,面向連接

2、工作在傳輸層面向連接協議

3、全雙工協議

4、半關閉(單方關閉)

5、錯誤檢查

每個數據包有編號,對方收到之後,會告訴發送方收到了,回給對方說我下次希望收到第n+1個包,假如發送了三個包,但是接受方只收到了兩個,會說下次希望收到第三個包,那麽就實現了錯誤檢查和重傳

6、將數據打包成段,排序

即標記序列號,有時候數據太大,會分成多個包,就需要有序列號,方便接收方組裝

7、確認機制

8、數據恢復,重傳

有時候傳輸會有丟包現象,那麽發送方會從接受方的回應包中知道丟的包是什麽,就會重傳。

9、流量控制,滑動窗口

10、擁塞控制,慢啟動(翻倍遞進)和擁塞避免算法

二、TCP包頭(最大60字節,固定首部20字節,選項40字節)

技術分享

▼ 源端口、目標端口:計算機上的進程要和其他進程通信是要通過計算機端口的,而一個計算機端口某個時刻只能被一個進程占用,所以通過指定源端口和目標端口,就可以知道是哪兩個進程需要通信。源端口、目標端口是用16位表示的,可推算計算機的端口個數為2^16個。

服務器端的端口號是固定的,客戶端的端口是隨機生成的。在Windows的命令行可以使用netstat -no 查看協議類型、本地地址、外部地址、狀態、端口號等。在linux中使用netstat -ntp

端口是計算機應用程序對應的端口,端口即相當於應用程序地址的作用。

▼ 序號(Sequence number):表示本報文段所發送數據的第一個字節的編號。在TCP連接中所傳送的字節流的每一個字節都會按順序編號。由於序列號由32位表示,所以每2^32個字節,就會出現序列號回繞,再次從0開始

▼ 確認號(Acknowledgment number):表示接收方期望收到發送方下一個報文段的第一個字節數據的編號。也就是告訴發送方:我希望你下次發送的數據的第一個字節數據的編號是這個確認號。即達到確認目的

▼ 數據偏移:表示TCP報文段的首部長度,共4位,由於TCP首部包含一個長度可變的選項部分,需要指定這個TCP報文段到底有多長。它指出TCP報文段的數據起始處距離TCP報文段的起始處有多遠。該字段的單位是32位(即4個字節為計算單位),4位二進制最大表示是15,所以數據偏移(也就是TCP首部)最大60字節

▼保留位:占6位,用不到。

▼ URG:表示本報文段中發送的數據是否包含緊急數據,占一位。後面的緊急指針字段(urgent pointer)只有當URG=1時才有效

▼ ACK:表示是否前面的確認號字段是否有效。ACK=1,表示有效。只有當ACK=1時,前面的確認號字段才有效。

TCP規定,連接建立後,ACK必須為1,帶ACK標誌的TCP報文段稱為確認報文段

▼ PSH:提示接收端應用程序應該立即從TCP接收緩沖區中讀走數據,為接收後續數據騰出空間。如果為1,則表示對方應當立即把數據提交給上層應用,而不是緩存起來,如果應用程序不將接收到的數據讀走,就會一直停留在TCP接收緩沖區中

▼ RST:如果收到一個RST=1的報文,說明與主機的連接出現了嚴重錯誤(如主機崩潰),必須釋放連接,然後再重新建立連接。或者說明上次發送給主機的數據有問題,主機拒絕響應,帶RST標誌的TCP報文段稱為復位報文段

▼ SYN:在建立連接時使用,用來同步序號。當SYN=1,ACK=0時,表示這是一個請求建立連接的報文段;當SYN=1,ACK=1時,表示對方同意建立連接。SYN=1,說明這是一個請求建立連接或同意建立連接的報文。只有在前兩次握手中SYN才置為1,帶SYN標誌的TCP報文段稱為同步報文段

▼ FIN:表示通知對方本端要關閉連接了,標記數據是否發送完畢。如果FIN=1,即告訴對方:“我的數據已經發送完畢,你可以釋放連接了”,帶FIN標誌的TCP報文段稱為結束報文段

▼ 窗口大小:占16位,表示現在充許對方發送的數據量,也就是告訴對方,從本報文段的確認號開始允許對方發送的數據量

▼ 校驗和(16位):提供額外的可靠性

▼ 緊急指針(16位):標記緊急數據在數據字段中的位置

▼ 選項部分(24位):長度可變,其最大長度可根據TCP首部長度進行推算。TCP首部長度用4位表示,選項部分最長為:(2^4-1)*4-20=40字節

▼ 填充(8位):用不到

三、常見選項

(1)最大報文段長度:MaxiumSegment Size,MSS

指明自己期望對方發送TCP報文段時那個數據字段的長度。默認是536字節。數據字段的長度加上TCP首部的長度才等於整個TCP報文段的長度。MSS不宜設的太大也不宜設的太小。若選擇太小,極端情況下,TCP報文段只含有1字節數據,在IP層傳輸的數據報的開銷至少有40字節(包括TCP報文段的首部和IP數據報的首部)。這樣,網絡的利用率就不會超過1/41。若TCP報文段非常長,那麽在IP層傳輸時就有可能要分解成多個短數據報片。在終點要把收到的各個短數據報片裝配成原來的TCP報文段。當傳輸出錯時還要進行重傳,這些也都會使開銷增大。因此MSS應盡可能大,只要在IP層傳輸時不需要再分片就行。在連接建立過程中,雙方都把自己能夠支持的MSS接入這一字段。MSS只出現在SYN報文中。即:MSS出現在SYN=1的報文段中

(2)窗口擴大:Windows Scaling

由於TCP首部的窗口大小字段長度是16位,所以其表示的最大數是65535。但是隨著時延和帶寬比較大的通信產生(如衛星通信),需要更大的窗口來滿足性能和吞吐率,所以產生了這個窗口擴大選項

(3)時間戳:Timestamps

可以用來計算RTT(往返時間),發送方發送TCP報文時,把當前的時間值放入時間戳字段,接收方收到後發送確認報文時,把這個時間戳字段的值復制到確認報文中,當發送方收到確認報文後即可計算出RTT。也可以用來防止回繞序號PAWS,也可以說可以用來區分相同序列號的不同報文。因為序列號用32為表示,每2^32個序列號就會產生回繞,那麽使用時間戳字段就很容易區分相同序列號的不同報文

(4)TCP協議端口號

★ 配置文件(範圍的定義):

/proc/sys/net/ipv4/ip_local_port_range

★ 傳輸層通過port號,確定應用層協議

★ tcp:傳輸控制協議,面向連接,通信前需要建立虛擬鏈路,結束後拆除鏈路(0-65535 即2^16-1)

★ udp:用戶數據包協議,無連接,不可靠(0-65535)

IANA:互聯網數字分配機構(負責域名,數字資源,協議分配)

★ 0-1023:系統端口或特權端口(僅管理員可用),是眾所周知的端口,永久的分配給固定的系統應用使用,22/tcp(ssh), 80/tcp(http), 443/tcp(https)

★ 1024-49151:用戶端口或註冊端口,但要求並不嚴格,分配給程序註冊為某應用使用,1433/tcp(SqlServer),1521/tcp(oracle),3306/tcp(mysql),11211/tcp/udp(memcached)

★ 49152-65535:動態端口或私有端口,客戶端程序隨機使用的端口

四、TCP的三次握手/四次揮手

1、TCP三次握手過程

技術分享

(1)過程:

Client-------------------------service

主動打開被動打開

1-----------SYN=1,seq=x------------->

2<---SYN=1,ACk=1,seq=y,ack=x+1--------

3-------ACK=1,seq=x+1,ack=y+1-------->

<----------------數據---------------->

(2)狀態切換

客戶端:

Closed--> SYN-SENT --> ESTAB-LISHED

關閉 同步已發送 已建立連接

客戶端本來處於關閉狀態,在發送完連接請求之後進入SYN-SENT狀態,在接收到服務器端的確認信息然後回給對方確認信息之後,就進入ESTAB-LISHED狀態,表示可以互相通信了。

服務器端:

Closed--> LISTEN --> SYN-RCVD --> ESTAB-LISHED

關閉 監聽 同步收到 已建立連接

一般服務器端直接就處於LISTEN監聽狀態,在收到客戶端連接請求並且回給客戶端確認信息之後就處於SYN-RCVD 狀態,在收到客戶端確認信息之後就處於ESTAB-LISHED狀態,表示可以互相通信了。

2、TCP四次分手過程

技術分享

(1)過程:

Client--------------------------Server

主動關閉被動關閉

1----------- FIN=1,seq=u ----------->

2<----- ACK=1,seq=v,ack=u+1 ---------

3<----- FIN=1,ACK=1,seq=w,ack=u+1 ----

4------ ACK=1,seq=u+1,ack=w+1 -------


(2)狀態切換:

客戶端:

ESTAB-LISHED --> FIN-WAIT-1 -- > FIN-WAIT-2 --> TIME-WAIT --> CLOSED

建立連接狀態 終止等待1 終止等待2 時間等待 關閉

客戶端本來處於ESTAB-LISHED建立連接狀態,在給服務器端發送了請求斷開後就進入FIN-WAIT-1狀態,在接收到服務器端發來的確認包之後,就進入FIN-WAIT-2狀態,之後在接收到服務器端發來的請求斷開包之後立即給服務器端發送確認包,然後就進入TIME-WAIT狀態(為了保證服務器端可以收到我的確認包),一般等待兩分鐘之後就進入CLOSED狀態。

服務器端:

ESTAB-LISHED --> CLOSE-WAIT --> LAST-ACK --> CLOSED

建立連接狀態 關閉等待 最後確認 關閉

服務器端本來處於ESTAB-LISHED建立連接狀態,在接收到客戶端的斷開連接請求並給客戶端發送確認包之後,進入CLOSE-WAIT狀態,然後給客戶端也發送斷開連接請求,就進入LAST-ACK狀態,在收到客戶端的確認包之後進入CLOSED狀態。


五、有限狀態機FSM(Finite State Machine)

CLOSED 沒有任何連接狀態

LISTEN 偵聽狀態,等待來自遠方TCP端口的連接請求

SYN-SENT 在發送連接請求後,等待對方確認

SYN-RECEIVED 在收到和發送一個連接請求後,等待對方確認

ESTABLISHED 代表傳輸連接建立,雙方進入數據傳送狀態

FIN-WAIT-1 主動關閉,主機已發送關閉連接請求,等待對方確認

FIN-WAIT-2 主動關閉,主機已收到對方關閉傳輸連接確認,等待對方發送關閉傳輸連接請求

TIME-WAIT 完成雙向傳輸連接關閉,等待所有分組消失(查看timewait時間 :cat /proc/sys/net/ipv4/tcp_fin_timeout )

CLOSE-WAIT 被動關閉,收到對方發來的關閉連接請求,並已確認

LAST-ACK 被動關閉,等待最後一個關閉傳輸連接確認,並等待所有分組消失

CLOSING 雙方同時嘗試關閉傳輸連接,等待對方確認


六、TCP超時重傳

異常網絡狀況下(開始出現超時或丟包),TCP控制數據傳輸以保證其承諾的可靠服務。TCP服務必須能夠重傳超時時間內未收到確認的TCP報文段。為此,TCP模塊為每個TCP報文段都維護一個重傳定時器,該定時器在TCP報文段第一次被發送時啟動。如果超時時間內未收到接收方的應答,TCP模塊將重傳TCP報文段並重置定時器。至於下次重傳的超時時間如何選擇,以及最多執行多少次重傳,就是TCP的重傳策略與TCP超時重傳相關的兩個內核參數決定的:

/proc/sys/net/ipv4/tcp_retries1,指定在底層IP接管之前TCP最少執行的重傳次數,默認值是3

/proc/sys/net/ipv4/tcp_retries,指定連接放棄前TCP最多可以執行的重傳次數,默認值15(一般對應13~30min)


七、滑動窗口

A主機給服務端發送一些包,等待服務端的回應,當返回信息為ack=4時則表示,表示服務器說我窗口大小為三,目前只能接收3個包,請求你發第四個包。


八、擁塞控制

TCP為提高網絡利用率,降低丟包率,並保證網絡資源對每條數據流的公平性。即所謂的擁塞控制。當網絡不好時就降低速度。

TCP擁塞控制的標準文檔是RFC 5681,其中詳細介紹了擁塞控制的四個部分:慢啟動(slow start)、擁塞避免(congestion avoidance)、快速重傳(fast retransmit)和快速恢復(fast recovery)。擁塞控制算法在Linux下有多種實現,比如reno算法、vegas算法和cubic算法等。 它們或者部分或者全部實現了上述四個部分

cat /proc/sys/net/ipv4/tcp_congestion_control 可以查看當前所使用的擁塞控制算法。

以上就是關於TCP的一些原理,希望能對大家有所幫助。

技術分享


TCP協議