天天看點

TCP三向交握與四次分手

TCP協定非常重要,這裡把它的連接配接和釋放整理一下。

首先是三次握手:

1、  用戶端發起,像伺服器發送的封包SYN=1,ACK=0,然後選擇了一個初始序号:seq=x。

SYN是幹什麼用的?

在連結的時候建立一個同步序号,當SYN=1同時ACK=0的時候,表明這是一個連接配接請求的封包段。如果對方有意連結,傳回的封包裡面SYN=1,ACK=1,。從這個意義上來說,SYN=1的時候,就表明這是一個‘請求’或者‘接受請求’的封包。

SYN=1的封包段不能攜帶資料。但是要消耗掉一個序号,

ACK是幹什麼用的?

僅當ACK=1的時候,确認字号(期望收到對方下一個封包段的第一個資料位元組的編号)才有效。是以,TCP規定,當連結建立之後,所有往來的封包裡面的ACK都應該是1(事實上,也隻有用戶端發起的連結請求封包的ACK沒有置1)。

現在的狀态:用戶端進入SYN-SEND狀态;

2、  伺服器接收到了SYN=1,ACK=0的請求封包之後,傳回一個SYN=1,ACK=1的确認封包。

同時,确認号ack=x+1,同時也為自己選擇一個初始序号seq=y

現在的狀态:伺服器進入SYN-REVD狀态;

3、  用戶端接收到了伺服器的傳回資訊之後,還要給伺服器傳回最後一條确認,ACK=1,确認号ack=y+1;

現在的狀态:用戶端進入ESTABLISHED狀态。

下面說一下為什麼兩次握手不行,非得三次:

首先說明一種正常的情況,就是用戶端發送了一條請求連結的封包,但是由于網絡原因丢失了,是以,不可能接收到伺服器端的确認。這個時候,用戶端就就隻有再一次發送原來的請求封包,這次伺服器收到之後傳回确認,用戶端再确認一次,連結确立。

然後考慮一種不正常的情況,用戶端發了兩次請求連結的封包,第二條被伺服器捕捉到,傳回資料,完成了兩次握手。資料傳送完成之後,連結關閉。但是這時候,第一條擁塞的請求封包現在到達了伺服器端,伺服器還以為用戶端要又一次建立連接配接,于是發送确認,然後把自己敞開,等着用戶端發送過來資料。于是,很多的網絡資源就是這樣浪費掉了。

要是實行三次握手,伺服器收到了一條過期的請求封包,傳回确認資訊,用戶端接收到了伺服器的資訊之後感到莫名其妙,心想:我他媽又沒要連結,你傳回這個是不是瘋了。于是不置一詞。伺服器過一段時間還沒有收到第三次握手的資料,知道用戶端并沒有要求建立連結的請求,含淚離開。

然後是四次分手:

現在雙方的狀态都是ESTABLISHED狀态。

1、  用戶端發起請求,請求斷開連結。FIN=1,seq=u。u是之前傳送過來的最後一個位元組的序号+1。

FIN:用來釋放一個連結,當FIN=1的時候,表明此封包的發送方已經完成了資料的發送,沒有新的資料要傳送,并要求釋放連結。

用戶端進入FIN-WAIT-1狀态,等着伺服器傳回确認;

2、  伺服器收到用戶端的請求斷開連結的封包之後,傳回确認資訊。ACK=1,seq=v,ack=u+1。

伺服器進入CLOSE-WAIT狀态。

這個時候,用戶端不能給伺服器發送資訊封包,隻能接收。但是伺服器要是還有資訊要傳給伺服器,仍然能傳送。

3、  當伺服器也沒有了可以傳的資訊之後,給用戶端發送請求結束的封包。FIN=1,ACK=1,

ack=u+1,seq=w。

這個時候的狀态:伺服器進入LAST-ACK狀态。

4、  用戶端接收到FIN=1的封包之後,傳回确認封包,ACK=1,seq=u+1,ack=w+1。

發送完畢之後,用戶端進入等待狀态,等待兩個時間周期。關閉。

為什麼最後還要等待兩個時間周期呢?

1、  用戶端的最後一個ACK封包在傳輸的時候丢失,伺服器并沒有接收到這個封包。這個候。

伺服器就會逾時重傳這個FIN消息,然後用戶端就會重新傳回最後一個ACK封包,等待兩個時間周期,完成關閉。如果不等待這兩個時間周期,伺服器重傳的那條消息就不會收到。伺服器就因為接收不到用戶端的資訊而無法正常關閉。

2、  預防上一次在三次握手中提到的失效的封包幹擾。兩個時間周期過去之後,所有的封包都會在網絡中消失,保證下一次重新連接配接的時候有亂七八糟的封包影響。

    本文轉自UVN2015  51CTO部落格,原文連結:http://blog.51cto.com/10851095/1952667,如需轉載請自行聯系原作者

繼續閱讀