TCP 學習筆記 --阿太

 

               TCP 學習筆記  --- Kindda Hu

                                         08.12.15  [email protected]

 

Reference: TCP/IP詳解卷一/ RFC793 /

 

以下是個人總結, 語言方面若有看不習慣請見諒. 還有幾點不明白之處請指教,請參考#Issues to be comfired. 若本人總結有錯誤之處,請各位及時指出並告知.

 

 

########## TCP Header ###################

 

 TCP Header Format 20Bytes

 

 

##########  TCP 基本傳輸流程#################

 

                                            Sender A ---------------->  Receiver  B

Step 1:Start 3-hands shake                

                                                     SYN seq j ,mss ,win

                                             a,    ------------------------->

                                                   SYN seq q,mss,win; ACK ack j+1

 

                                             b,   <-------------------------

                                                     seq j+1 ACK ack q+1

                                             c,    ------------------------->

 

Step 2: Data flow  

       2.1 數據不需要分組,                     

                                                   seq j+1, ack NO (Length), 

                                             d,   ------------------------->

                                                   ack (j+length+1), win size

                                             e,   <-------------------------

                                                

     2.1 數據包進行分組轉發,絕大多數都需要如此發送:

                                                   

                                                   seq j+1, ack seq no (Length), 

                                              f,   ------------------------->

                                                   ack (j+length+2), win size

                                              g,  <------------------------- 

 

                                                 seq j+length,ack no(length),win size,

                                              h,   ------------------------->

 

                                                seq (j+length+length),ack no(length),win size,

                                              i,   ------------------------->

                                                  ack j+length+1;win size

                                              j,  <-------------------------

                                                  ack j+length+length+1;

                                              k,   ------------------------->

                                                      .................

 

                                                

Step 3, Close. FIN  4 hands shake

                                                 Fin seq j',

                                              l  ------------------------->     

                                                ACK seq j'+1

                                             m <-------------------------  

                                                Fin seq q'

                                              n <------------------------- 

                                                ACK seq q'+1

                                              o ------------------------->  

 

 

Step1 ,  TCP 建立, 3次握手; 下面爲正常的TCP session建立過程;

           a. A主動建立TCP連接, 發送SYN , seq no爲當前定時器給的值j(參見關於SEQ NO),宣稱自己的MSS, window size;

           b. B回覆ACK, ack no = j+1,並同時發SYN包給發A, seq noB自身定時器的值q, 並宣稱自己的msswin size;

           c. A收到B發來的SYN包後回覆ACK, ack no=q+1;

  ps: Step1爲標準的正常TCP session建立流程,還有一些非正常現象,AB同時向對方發送SYN,則通過4次握手只建立一個TCP            session;

 

Step2,   數據傳輸, TCP session建立後,AB發送數據包

      2.1  數據不需要分組傳輸,每個數據包單獨傳輸.

           d. AB發送數據包,Seq noj+1,和步驟c中的seq no相同, 因爲A並沒有收到B發送新的ack no,length爲數據的長度(因爲需要發               送的數

 

據字節長度小於MSSwin size,所以不需要分段), (參考關於數據包分組(分段)傳輸標準);

           e. B收到數據後給A回覆ACK, ack noj+1+length;

 ps:

      2.2  數據需要進行分組傳輸

           f. AB發送一個數據報文,seq noj+1, 長度爲length;

           g.BA剛纔的data報文回覆ACK, ack noj+1+length+1;

           h.A收到B對於剛發送data包的ack, 使用其ack no作爲seq no發送數據,lengthl';

           i. A使用seq no j+1+length+1+L'再次發送數據報文; (連續發送兩個數據包. 發送方接收到一個ack則增加一個發送數據包.因爲使用了慢啓動. 詳情

 

請參照 關於慢啓動)

           j. B收到2data包後回覆ack(根據網絡情況和b決定. 只回復一個ack或者針對每個data都回復ack. 具體參考關於接收方什麼時候回覆ACK報文)

           k. 很步驟h類似, 這次發送的data數根據收到的ack報文來決定,收到n個則再增加n;

 

Step3, 結束TCP Session,

        TCP session的結束類似於TCP session的建立(只不過將給對方的ack和自己的fin請求區分開了), 需要分別想對方發送FIN請求,並得到對方的ack

 

close掉此鏈接;

           l. 當數據發送完成後,發送方A給接收方B發送FIN結束請求, seqj';

          m.B收到Fin,回覆ACK報文給A;

           n.BA發送FIN請求結束報文;

           o.A收到ACK後結束對BTCP 狀態調整爲closed; 並在收到B發送的Fin,回覆ACKB; B在收到ack後將自己對於Atcp狀態調整爲closed;

 ps: 有的TCP版本中,結束時只進行單方面結束,即兩次握手,ABFIN,B回覆ACK,但是不發送Fin請求;

            

 

 

######### TCP 狀態變遷 ###############

 

# 如下圖爲TCP狀態機圖

 

 

#如下圖爲正常的T C P連接的建立與終止過程中,客戶與服務器所經歷的不同狀態。

Ps: 主動結束的需要先進入Time-wait狀態後經過2MSL後進入Closed狀態;

 

 

 

   被動結束的,只需要在LAST-ACK狀態中收到ACK回覆即可進入Clolse狀態;

因爲提出主動結束的大都爲客戶端,所以服務器被動結束,直接進入Closed狀態.

 

 

### 下面爲TCP 各種狀態的具體說明

A connection progresses through a series of states during its

lifetime. The states are: LISTEN, SYN-SENT, SYN-RECEIVED,

ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK,

TIME-WAIT, and the fictional state CLOSED.

CLOSED is fictional because it represents the state when there is no TCB, and therefore,no connection. Briefly the meanings of the states are:

 

LISTEN - represents waiting for a connection request from any remote

TCP and port. 監聽狀態;

 

SYN-SENT - represents waiting for a matching connection request

after having sent a connection request. Syn已經發出狀態;

 

SYN-RECEIVED - represents waiting for a confirming connection

request acknowledgment after having both received and sent a

connection request. 收到SYN,回覆ack併發送SYN;

 

ESTABLISHED - represents an open connection, data received can be

delivered to the user. The normal state for the data transfer phase

of the connection. 收到針對自己發出SYN包的ACK報文,則變成Estab狀態;

 

FIN-WAIT-1 - represents waiting for a connection termination request

from the remote TCP, or an acknowledgment of the connection

termination request previously sent. 主動結束中,發送FIN報文,並等待ACK或者Fin的階段;

 

FIN-WAIT-2 - represents waiting for a connection termination request

from the remote TCP. 主動結束中,接收到針對自己發出FIN包的ACK.並等待對方FIN包的階段;

 

CLOSING - represents waiting for a connection termination request

acknowledgment from the remote TCP. 主動結束中,FIN-Wait1狀態,等待對方ACK包的過程中收到對方的主動結束請求FIN,則進入CLOSING階段;

 

TIME-WAIT - represents waiting for enough time to pass to be sure

the remote TCP received the acknowledgment of its connection

termination request.

 

CLOSE-WAIT - represents waiting for a connection termination request

from the local user.被動結束中,收到對方的FIN請求,回覆ACK報文的階段;

 

LAST-ACK - represents waiting for an acknowledgment of the

connection termination request previously sent to the remote TCP

(which includes an acknowledgment of its connection termination

request). 被動結束中,COLSE-WAIT的基礎上,發送FIN請求後,等待ACK報文的階段 ;

 

CLOSED - represents no connection state at all. 主動結束時,Time-WAIT經過2msl到達Colsed; 被動結束時, LAST-ACK報文收到最後的ack後進入的狀態.

 

 

################## 相關概念 ###########################3

 

sender 相關概念:MTU,MSS,window size 的左邊, Cwnd(congetion window size) 慢啓動門限ssthresh, RTT, RTO,

Receiver 相關概念: MRU,MSS,window size的右邊,  window size,buffer size, tcp 處理進程, 回覆ack. window size buffer size seq no ack no

 

 

#關於PUSH標記

若接收方收到一個帶PSH標誌的包,則立即提交到TCP進程進行處理,並回復ACK.  若數據包中不帶PSH標記, 則是由分組到齊或者buffer size到一定程度上將數據

 

提交到TCP處理進程中.

 

#關於SEQ NO

seq NO 爲數據包發送的序列號, TCP 報頭中包括Seq no ack seq NO,分別佔4個字節,  所以其值爲[ 0- 65535x65535].

第一個syn包中的seq no值由發送方的定時器決定. Seq No 由一個定時器維護着,每隔4ms, seq+1, 達到最大值後繼續衝最小值開始循環, 如此反覆;

數據傳輸時的seq no (我認爲)ack回覆的ack no爲準, = sender's seq +1;也可是發送方的原seq no+Length+1; (RFC793中如此規定,但是也有不同實現的.)

 

#關於DATA Offset

數據開始的偏移位數,就是說從x個字節開始爲數據, x之間的爲TCP Header,所以也可解釋爲TCP 頭部的長度.   但是x=nx4;offset4bit1000的話,10進製爲8,所以tcp header長度爲8x4=32;

 

###### 關於定時器 ##########

## 關於堅持定時器 Persist Timer:

 即窗口大小檢測定時器, 發送方通過該定時器定期查詢接收方窗口狀態. 防止一下情況產生,

a,  receever win size0,並通知sender,sender 暫停發送報文,並等待窗口更新報文ack的到來;

b,  receiver 窗口更新, 發送ack通知sender,但是該ack包被丟失.

c,  則出現了, sender 等待win size更新報文,不發送數據; receiver 等待sender發送新的數據的 雙方互等的情況發生.

 

persist timer 在收到win size0ack包時被啓動,然後每隔一段(5s)時間進行查詢.

receiver window size 需要從從0更新到大於1/2buffer size的時候,才告知sender,否則仍然宣稱win = 0 ;

 

## 關於保活定時器 Keepalive Timer:

可以理解爲TCP Session timeout keepalive time, 當建立好的tcp session處於空閒時,雙方都處於Established狀態,保活定時器則可以在一段時間以後自動停

 

止該tcp session.   但是RFC和有的TCP版本並不支持該定時器.

 

## 關於2MSL 定時器 

 

 

 

 

##關於判斷是否分組的標準:

首先理解下面幾個概念: 需要傳輸的數據字節數, MSS,MTU, Window size;

#關於需要傳輸的數據字節數.

既被傳輸數據的字節個數. ("Hello World"10個字節.若每次只發送一個hello world,則每次爲10個字節; 若一次發送200hello word,則需要傳輸的字節數

 

2000個字節;)

#關於MSS/MTU/WINDOW SIZE則參考關於MSS,關於MTU和關於Window size;

 

#關於MTU

MTU 爲最大傳輸單元,基於不同的鏈路層的. Ehternet MTU 1518, SLIP259,  所以相對爲IP層來說,MTU= 1518-18(DMAC 6+SMAC 6+

 

TYPE/LENGTH 2+ CRC 4)= 1500; 相對於PPPoE來說,MTU= 1492=1500-8(PPP);

 

#關於MSS

MSS TCP協議裏面的一個概念,爲發送端最大發送的TCP報文中數據字段的大小,必須小於MTU,通常爲 1460=

 

MTU-IPHead-TCPhead=1500-20-20=1460;

A-B都在同一網段,MSS1460,若不在同一網段,而且程序沒有指定的話,使用默認536;

MSS一般在TCP session建立階段 三次握手時宣稱和協商.

 

#window size

window size  接收端用來申明自己可以接收到的數據大小爲窗口;  接收端用此來處理數據擁塞;

數據傳輸時, 窗口是滑動的, 可以理解爲窗口大小爲從AB,A代表窗口的左邊, B代表窗口的右邊, 所以Window size == B-A; 在傳輸過程中BA都向後滑動,

 

B=A, window size == 0, 接收方此時不能接收任何數據, 並通知發送方讓其停止發送數據, 當窗口大小更新後,發送ack通知sender告知window 大小,

 

sender繼續發送數據.

發送端左邊A向右移動,是因爲受到接收端的ack包,並將左邊A移動到ack no的地方.

接收端window size右邊B向右移地取決於, 接收端進程處理tcp數據並釋放緩存的能力。 當緩存沒有釋放完全時,接收端則通過ack給發送端通告當前window

 

size的大小,待恢復或者變大時,發ack包通知, ack no和之前的ack包中的no 相同。 所以說buffer可以大於緩存。

接收方回覆ACK的時機 取決於接收方window size的大小(接收方在發送一個A C K前不必等待窗口被填滿)和接收到的包中是否帶有PUSH標記.)?

 

下面說一下我對於什麼時候需要對數據包分段的理解:

比如說一個正常的數據傳輸, MSS=1460,MTU=1500,Win size=65535; 當前win sizeB通告的爲win size',

1, 當要發送數據字節個數<MSS;且又<win size' ; 不需要分組發送; 如發送hello word 或者通過telnet登錄時傳輸user/password的報文;

2, 當要發送數據字節數>MSS;且又>win size', 則需要進行分組發送;ftp傳輸大文件,或者一次傳輸200hello world(注意:一次發送200hello world和發

 

200hello word是不一樣的. 前者需要分組,2date報文搞定(length分別是1460+540)和一個ack報文;而後者則需要200date報文(每個length=10),

 

x(有時爲200,有時爲x,請參考關於接收方什麼時候回覆ACK報文)ack報文.);

 

 

##關於如何決定是否重發數據包.(如何界定包已經丟失並重傳?)    

1,RTO超時;

2,連續收到3個相同Seq noack,發送方則認爲丟包.

                                                                

 

#### TCP 對分組包丟失的處理 #########

當分組傳輸的數據被丟失後, 接收端通過對收到的數據進行處理髮現後,必須發送ack報文通知發送方重新發送. 

因爲TCP無法告知對方缺少那一段,所以採用發送方將自己最後一個成功回覆的ack包發送給對方的方式,來告訴對方應該從該seq no處將數據包進行重發.

發送方連續收到3個相同的ACK, 則認爲有包被丟棄,並重傳自那個序號起的一段報文.

當接收方處於通知對方丟包並且在等待丟失包到來的狀態時, 對收到的數據包只進行保存,不會上傳到進程進行處理.

當接收方收到丟失包且發現沒有其他丟包時, 將緩存的數據全部提交給進程進行處理.

 

# 慢啓動和擁塞避免

Congetion window 發送端每次發送數據包的個數大小,cwnd<= ssthresh,每當收到一個ack,cwnd+1; cwnd>ssthersh,則每次增

 

1/cwnd,cwnd=cwnd+1/cwnd. 發送方用此來進行數據擁塞的處理.

 

 

 

## 關於重傳超時定時器 Retransmission TimeOut / RTT :

RTO 爲超時重傳時間. RTO時間內未收到對方的ack,則認爲超時,重發數據包;

RTO值是有RTT計算出來, RTT 爲往返時間, 爲發送方發出一個seq no的報文,到收到該報文ack 回覆的時間段.由於網絡流量變化,所以TCP需要跟蹤這些變化,

 

並算出相應的值;  所以TCP中判斷是否超時,重傳最主要的就是要進行RTT的計算.

sender 每次發送數據要先檢測RTT 測量定時器是否被啓動,若沒有的話則啓動該定時器, 若已經啓動的話則不更新.

因爲TCPackseq no的回覆並不可能是一一對應,所以需要算法來計算RTT的值;

 

 

 

### Issues to be confirmed  #####

1, 接收方什麼時候會將buffer中的數據提交到TCP進程當中去?

  包中帶psh標記, buffer 到什麼程度? 還是等分組全部收到? 或者自己有什麼定時器?

 

2, TCP 不對ack報文進行確認,只對帶有帶有數據的ack報文進行確認.  應該如何理解!!????????

 

3, RTO 本身有定時器? rtt測量定時器!? 是否是每次發送方發送數據前要確認啓動的定時器?

 

4,關於接收方B什麼時候回覆ACK報文?

 

5,關於2MSL 定時器 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章