TCP三次握手建立連接與四次握手終止連接及sep和ack號的正確理解

一、簡介


TCP連接是面向連接的,所謂的面向連接就是,當計算機雙向通信時必需先建立連接,然後才能進行數據的傳輸,最後還要拆除連接。而同在一個網絡層的UDP傳輸,是面向非連接的傳輸,也不是可靠的。
TCP建立連接需要三次握手的過程,而拆除連接需要四次握手的過程。

二、TCP連接的建立與終止

1、TCP連接的建立(三次握手):

•在TCP/IP協議中,TCP協議提供可靠的連接服務,採用三次握手建立一個連接。
•第一次握手:建立連接時,客戶端發送syn包(syn=j)到服務器,並進入SYN_SEND狀態,等待服務器確認;
•第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;
•第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。
•完成三次握手,客戶端與服務器開始傳送數據.


  TCP三次握手建立連接如下圖所示:




注:位碼即tcp標誌位,有6種標示:
SYN(synchronous建立聯機) ACK(acknowledgement 確認)PSH(push傳送) 
FIN(finish結束)RST(reset重置)URG(urgent緊急)

Sequence number(順序號碼) Acknowledge number(確認號碼)

未連接隊列:
在三次握手協議中,服務器維護一個未連接隊列,該隊列爲每個客戶端的SYN包(syn=j)開設一個條目,該條目表明服務器已收到SYN 包,並向客戶發出確認,正在等待客戶的確認包。這些條目所標識的連接在服務器處於Syn_RECV狀態,當服務器收到客戶的確認包時,刪除該條目,服務器 進入ESTABLISHED狀態。Backlog參數:表示未連接隊列的最大容納數目。
SYN-ACK重傳次數 :
服務器發送完SYN-ACK包,如果未收到客戶確認包,服務器進行首次重傳,等待一段時間仍未收到客戶確認包,進行第二次重傳,如果重傳次數超 過系統規定的最大重傳次數,系統將該連接信息從半連接隊列中刪除。

注意,每次重傳等待的時間不一定相同。
半連接存活時間:是指半連接隊列的條目存活的最長時間,也即服務從收到SYN包到確認這個報文無效的最長時間,該時間值是所有重傳請求包的最長等待時間總和。有時我們也稱半連接存活時間爲Timeout時間、SYN_RECV存活時間。

TCP選項:
每一個SYN可以含有若干個TCP選項,通常使用的選項有:
(1)MSS選項:TCP發送的SYN中,帶有這個選項是通知對方它的最大分節大小MSS(maximum segment size),即它能接受的每個TCP分節中的最大數據量,可以使用TCP_MAXSEG套接口選項獲取與設置這個TCP選項(Linux系統下)。
(2)窗口規模選項:TCP雙方能夠通知對方的最大窗口大小是65535,因爲TCP頭部相應的字段只佔16位,這個選項指定TCP頭部的廣告窗口必須擴大(左移)的位數(0--14),因此所提供的最大窗口幾乎是1G字節(65535*2的14次方)
(3)時間戳選項:這個這項對高速連接是必要的,它可以防止失而復得的分組可能造成的數據損壞,也就是說是暫時的路由原因造成的迷途的分組,當路由穩定後,它們又會正常到達目的地,其前提是它們在此前尚未被路由主動丟棄。

2、TCP斷開連接(四次握手):

由於TCP連接是全雙工的,因此每個方向都必須單獨進行關閉。這原則是當一方完成它的數據發送任務後就能發送一個FIN來終止這個方向的連接。收到一個FIN只意味着這一方向上沒有數據流動,一個TCP連接在收到一個FIN後仍能發送數據。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。
四次握手:
(1)TCP客戶端發送一個FIN,用來關閉客戶到服務器的數據傳送(報文段4)。
(2) 服務器收到這個FIN,它發回一個ACK,確認序號爲收到的序號加1(報文段5)。和SYN一樣,一個FIN將佔用一個序號。
(3) 服務器關閉客戶端的連接,發送一個FIN給客戶端(報文段6)。
(4) 客戶段發回ACK報文確認,並將確認序號設置爲收到序號加1(報文段7)。

四次握手斷開連接具體過程如下圖所示:



注意:四次揮手不是關閉TCP連接的唯一方法. 有時,如果主機需要儘快關閉連接(或連接超時,端口或主機不可達),RST (Reset)包將被髮送. 由於RST包不是TCP連接中的必須部分, 可以只發送RST包(即不帶ACK標記). 但在正常的TCP連接中RST包可以帶ACK確認標記請注意RST包是可以不要收到方確認的。

三、TCP連接seq和ack號的正確理解

1、TCP協議結構:



2、握手階段:

序號方向seq ack1標誌位
(1) A->B10000SYN=1
(2) B->A2000010001=10000+1SYN=1, ACK=1
(3) A->B1000120001=20000+1ACK=1

解釋
(1)A向B發起連接請求,以一個隨機數初始化A的seq,這裏假設爲10000,此時ACK=0
(2)B收到A的連接請求後,也以一個隨機數初始化B的seq,這裏假設爲20000,意思是:你的請求我已收到,我這方的數據流就從這個數開始。B的ACK是A的seq加1,即10000+1=10001
(3)A收到B的回覆後,它的seq是它的上個請求的seq加1,即10000+1=10001,意思也是:你的回覆我收到了,我這方的數據流就從這個數開始。A此時的ACK是B的seq加1,即20000+1=20001


3、揮手階段:

序號方向seq ack1標誌位
(1) A->B1000120001FIN=1, ACK=1
(2) B->A10002=10001+1ACK=1
(3) B->A2000110002=10001+1FIN=1, ACK=1
(4) A->B20002ACK=1

解釋
(1)A向B發起斷開連接請求,A的seq爲之前的值10001沒變,此時ACK也爲上一次的值20001沒變;
(2)B收到A的斷開連接請求後,向A發送確認斷開連接,ACK爲A的seq加1,即10001+1=10002,同事ACK標誌位置1,意思是:你的主動斷開連接請求我已收到,將關閉從A到B的數據傳送;
(3)B向A發送斷開連接請求,它的seq是A的ACK,即20001;
(4)A收到B的斷開連接請求後,向B發送確認斷開連接,ACK爲B的seq加1,即20001+1=20002,同事ACK標誌位置1,意思是:你的主動斷開連接請求我已收到,將關閉從B到A的數據傳送;

4、數據傳送階段:

序號方向seq ack1size
(1) A->B40007000100
(2) B->A70004100=4000+10054
(3) A->B41007054=7000+54100
(4) B->A70544200=4100+100 54

解釋:
(1)B接收到A發來的seq=4000,ack=7000,size=100的數據包
(2)於是B向A也發一個數據包,告訴B,你的上個包我收到了。B的seq就以它收到的數據包的ACK填充,ACK是它收到的數據包的SEQ加上數據包的大小(不包括以太網協議頭,IP頭,TCP頭),以證實B發過來的數據全收到了。
(3)A 在收到B發過來的ack爲4100的數據包時,一看到4100,正好是它的上個數據包的seq加上包的大小,就明白,上次發送的數據包已安全到達。於 是它再發一個數據包給B。這個正在發送的數據包的seq也以它收到的數據包的ACK填充,ACK就以它收到的數據包的seq(7000)加上包的 size(54)填充,即ack=70000+54(全是頭長,沒數據項)。
(4)B向A也發一個數據包,B的seq就以它收到的數據包的ACK填充,ACK是它收到的數據包的SEQ(4100)加上數據包的大小100(不包括以太網協議頭,IP頭,TCP頭);
其實在握手和結束時確認號應該是對方序列號加1,傳輸數據時則是對方序列號加上對方攜帶應用層數據的長度.如果從以太網包返回來計算所加的長度,就嫌走彎路了.
另外,如果對方沒有數據過來,則自己的確認號不變,序列號爲上次的序列號加上本次應用層數據發送長度.


四、爲什麼建立連接協議是三次握手,而關閉連接卻是四次握手呢?

這是因爲服務端的LISTEN狀態下的SOCKET當收到SYN報文的建連請求後,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裏來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可以未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這裏的ACK報文和FIN報文多數情況下都是分開發送的.


本文參考資料來自:

http://blog.chinaunix.net/uid-25513153-id-187780.html

http://blog.chinaunix.net/uid-20788636-id-1841260.html

位碼即tc標誌位,6種標示:

SYN(synchronous建立聯機)      ACK(acknowledgement確認) PSH(push傳送)                          FIN(finish結束)

RST(reset重置)                          URG(urgent緊急)

Sequence number(順序號碼)    Acknowledge number(確認號碼)

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