網絡是如何連接起來的?詳解TCP三次握手

從HTTP說起

互聯網的通信都是遵循著一定的協議的,通信雙方必須經過一些約定俗成的協議才能互相通信,不然我說中文,你說英文,兩者相互聽不懂對方的消息,這樣是無法通信的,因此就必須約定雙方都說中文或者英文,這樣雙方才能完美地進行通信。因此,互聯網中一定得存在著各種各樣的通信協議,才能相互的通信。

當我們使用瀏覽器訪問某網站的時候,如當訪問百度的時候,瀏覽器都會自動地在www.baidu.com前面加上http://這個東東,變成http://www.baidu.com,然後再去發起請求。http://這個東東就表明了我們的瀏覽器是以http協議去訪問百度的服務器的。

那麼是不是單單隻有這種協議呢,不,完成不同的需求就需要不同的協議,比如上述的網頁訪問用到了HTTP協議,還有為提供可靠且有效的電子郵件傳輸而定義的SMTP協議、基於文件的傳輸而定義了FTP協議等等,這些協議都是應用層級別的協議,在計算機網絡中,為了降低耦合度,類似函數之間的方法調用,採用了協議棧的概念,有OSI七層協議體系結構,也有TCP/IP四層協議體系結構,我們經常採用的是綜合兩者的有點,定義了一種只有五層協議的體系結構。傳輸層、網絡層、數據鏈路層的協議都是通過操作系統內核去處理的,而應用層通過調用這些操作系統內核的代碼去實現的,因此,可以說應用層的協議是基於下面的協議而實現的。

網絡是如何連接起來的?詳解TCP三次握手

因此瀏覽器訪問服務器的過程就可以抽象為如下圖,這也是http協議的基本工作方式。客戶進程(瀏覽器)的位置在最高的應用層,它向服務器主機的應用層服務器進程發出請求,請求建立連接,然後,服務器進程接受客戶進程發來的請求。http只是一個應用層級別的協議,其實HTTP協議又是基於TCP協議的,TCP協議是傳輸層的東西。

網絡是如何連接起來的?詳解TCP三次握手

因此,更具體一點,所有的這些通信,實際上都需要使用下面各層所提供的服務,可以表現為下圖。

網絡是如何連接起來的?詳解TCP三次握手

可以看出HTTP協議定義了通信的雙方通信前必須要建立好連接,HTTP協議又是通過TCP協議去實現的,因此,HTTP中連接的建立、數據傳送和連接的釋放實則是由HTTP的底下運輸層中的TCP協議去實現的。HTTP協議只是在TCP協議的基礎上定義了一些屬於自己的東西。


TCP的連接建立

因為TCP連接是可靠的連接,因此必須保障每一方都能夠確知對方的存在,所以必須先經過建立連接的過程,使雙方都在連接上,每一方都知道對方存在,才是保障可靠連接的前提。TCP建立連接的過程叫做握手,握手需要在客戶與服務器之間交換三個TCP報文段,如下圖為TCP建立連接的三次握手過程。

網絡是如何連接起來的?詳解TCP三次握手

上圖中客戶端有CLOSED、SYN-SENT、ESTABLISHED三種狀態,服務器有CLOSED、LISTEN、SYN-RCVD、ESTABLISHED四種狀態。

CLOSED為關閉狀態,是客戶端與服務器端沒有進行任何操作時候的狀態,當服務器端開啟監聽端口的時候,服務器端變成LISTEN狀態,監聽和接收客戶端的請求連接報文。

① 客戶端發出打算建立TCP連接的請求報文,報文首部中的SYN位=1,說明該報文不能攜帶數據,但是要消耗一個序號(seq)。TCP是面向字節流的,在一個TCP連接中傳送的字節流中的每一個字節都按順序編號,該編號即為序號(seq)。該請求建立連接報文中選擇一個初始序號seq=x,但是不攜帶數據。此時,TCP客戶端進程進入SYN-SENT(同步已發送)狀態。

② 服務端監聽端口接收到請求後,如同意建立連接,則向客戶端發送確認。在確認報文段中將SYN位和ACK位都置為1,SYN位=1說明該報文不攜帶數據,但同樣也要消耗掉一個序號和選擇一個初始序號seq=y。ACK位=1說明該報文中的確認號有效,確認號是ack=x+1,表示希望客戶端傳輸的下一個序號為x+1(因為客戶端在第一步已經發了一個序號為x的報文)。此時TCP服務器進程進入SYN-RCVD(同步收到)狀態。

③ 客戶端收到服務器的確認後,還要給服務器發出確認,故先將該確認報文段的ACK置為1,確認號ack=y+1,表示希望服務器端傳輸的下一個序號為y+1(因為服務器在上一步中已經發了一個序號為y的報文),而自己的序號為seq=x+1。此時,TCP連接已經建立,雙方都進入ESTABLISHED(已建立連接)狀態。

還不明白?我們用通俗的話再來描述以上的三次握手過程!

① 客戶端:服務器,我們可以建立連接嗎?

② 服務器:可以啊,我們建立連接吧!

③ 客戶端:收到,建立連接吧!

然後建立TCP連接成功

如果是四次握手的話,就變成了如下

① 客戶端:服務器,我們可以建立連接嗎?

② 服務器:可以啊,我們建立連接吧!

③ 客戶端:收到,我們建立連接吧!

④ 服務器:收到,我們建立連接吧!

然後建立TCP連接成功

服務器在②中都已經答應建立連接了,就不用再答應建立連接了,因此第4次握手是沒有必要的。

那為什麼不來2次握手呢?

① 客戶端:服務器,我們可以建立連接嗎?

② 服務器:可以啊,我們建立連接吧!


第一個原因:

兩次握手中,客戶端知道了服務器具有接收信息和發送信息的能力,但是服務器只知道客戶端具有發送信息的能力,但是並不知道客戶端具有接收信息的能力,如果加上第3次握手,服務器就知道了客戶端具有接收信息的能力(因為客戶端接收到了信息並且回覆給服務器端)。

第二個原因:

現在考慮這麼一種情況,由於網絡擁堵,客戶端發出的第一個連接請求報文段(第一次握手)在某些網絡節點長時間滯留了,需要一些時間才能到達服務器。

網絡是如何連接起來的?詳解TCP三次握手

然後由於客戶端沒有收到服務器的確認報文,客戶端就認為這個連接請求報文段(第一次握手)失效了,於是重新發送這個連接請求報文,這一次沒有因為網絡堵塞而滯留在網絡中,成功發送到服務器端了,因為是兩次握手,所以兩次握手後,連接就成功建立了。

網絡是如何連接起來的?詳解TCP三次握手

客戶端認為剛開始的那個由於網絡擁堵而滯留在網絡中的請求連接報文失效了,其實並沒有失效,只是由於網絡的擁堵而滯留在網絡中而已,此時,網絡不阻塞了,又暢通了,該報文成功到達了服務器,服務器又以為客戶端要進行與服務器TCP的連接,於是服務器就又對這個連接請求報文進行應答,同意建立連接。假定不採用第三次握手,那麼只要服務器發出確認,新的連接就建立了。

網絡是如何連接起來的?詳解TCP三次握手

由於現在客戶端並沒有發出建立連接的請求,因此不會理睬服務器端的確認,也不會向服務器端發送數據。但服務器端卻以為新的運輸連接已經建立了,並一直等待客戶端發來數據。服務器端的許多資源就這樣白白浪費了。

網絡是如何連接起來的?詳解TCP三次握手

因此,需要第三次握手來解決該問題,第三次握手是客戶端發給服務器端的確認報文,如果服務器端過了規定的時間都沒收到客戶端的回覆確認報文,於是也不會為客戶端分配資源,因此,此次的連接就放棄啦,也不會耗費服務器端的資源了。

全文完


分享到:


相關文章: