TCP時是向連接的協議,運輸連接是用來傳送TCP報文的,
這里我們討論TCP連接的建立:三次握手
首先看圖解:

第一次握手:
- 客戶端向服務器端發送請求,
此時首部中的同步位SYN=1,(當SYN=1,表示這是一個請求報文段,對方若同意連接,則在回應的報文段中使用SYN=1和ACK=1)
同時選擇一個初始序號seq=x;(表示發送的序列,可以通過這個序號檢測傳輸程序是否丟包)
第二次握手:
- 服務器收到請求包文段后,如果同意建立連接,則向客戶端發送確認,
上一步所示,如果同意首先要回傳SYN=1和ACK=1
然后回傳確認號ack=x+1,(確認號,表示期望收到對方下一個報文段的第一個資料位元組的序號)
同時給自己選擇一個初始序列號seq=y
第三次握手:
- 此時客戶端已經知道可以向服務器發送資料,并且能夠接收服務器端的資料,
- 但是服務器僅僅知道能夠接收客戶端發送的訊息,自己發送的資料不知道客戶端是否能接收到,因此還需要第三次握手
- 客戶端收到服務器的確認后,還要向服務器給出確認
此時已經知道能夠連接,就不需要請求報文段SYN了
此時回傳確認報文段ACK=1,
回傳確認號,即ack=y+1,(希望服務器下一個發送報文段的第一個資料位元組的序號)
同時自己的序號seq=x+1
上面就是三次握手的三個部分,
三次握手的原因?為什么不是兩次
三次握手可以防止已經失效的連接請求報文突然又傳輸到服務器導致的服務器資源浪費
tcp是全雙工通信,兩次握手只能確定單向資料鏈路是可以進行通信的,并不能保證反向的通信正常,
eg:
客戶端先發送了一個SYN,但是由于網路阻塞,該SYN資料包在某個節點長期滯留,
然后客戶端又重傳SYN資料包并正確建立TCP連接,然后傳輸完資料包后關閉該連接,該連接釋放后失效的SYN資料包才到達服務器端,
在二次握手的前提下,服務器會認為這是客戶端發起的又一次請求,然后發送SYN,并且在服務器端創建socket套接字,一直等待客戶端發送資料,
由于客戶端并沒有發起新的請求,所以會丟棄服務器的SYN,此時服務器會一直等待客戶端發送資料從而造成資源浪費
但是如果是三次握手,此時當客戶端收到SYN后,并不會直接丟棄,而是再次向服務器發送RST報文,表示終止,服務器接收到訊息之后就會把新創建的socket套接字釋放,從而避免了資源浪費,
為什么不是四次?
本來握手和揮手一樣都是需要確認兩個方向都能聯通的,本來模型應該是:
- 客戶端發送syn0給服務器
- 服務器收到syn0,回復ack(syn0+1)
- 服務器發送syn1
- 客戶端收到syn1,回復ack(syn1+1)
因為tcp是全雙工的,上邊的四步確定了資料在兩個方向上都是可以正確到達的,但是2,3步沒有上下的聯系,可以將其合并,加快握手效率,所以就變成了三次握手,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/254781.html
標籤:其他
上一篇:談談作業中常用的設計模式
