網絡是怎樣連接的學習筆記-第二章-連接服務器
2.2 連接服務器
2.2.1 連接是什麽意思
連接時發生了什麽
客戶端創建套接字告知服務器我要通信
創建套接字之後,應用程序就會調用 connect。隨後協議棧會將本地的套接字與服務器的套接字進行連接。
在調用 socket 創建套接字時,我們需要把服務器的 IP 地址和端口號等信息告知協議棧,這是連接操作的目服務器上也會創建套接字的之一。
服務器等待客戶端發送我要通信的消息
服務器上的協議棧和客戶端一樣,只創建套接字的。和客戶端不同的是,在服務器上連應用程序也不知道通信對象是誰。
我們需要讓客戶端向服務器告知必要的信息,客戶端向服務器傳達開始通信的請求,也是連接操作的目的之一。
連接時實際是在做什麽
連接實際上是通信雙方交換控制信息,在套接字中記錄這些必要信息並準備數據收發的一連串操作
客戶端將 IP地址和端口號告知服務器這樣的過程就屬於交換控制信息的一個具體的例子。
所謂控制信息,就是用來控制數據收發操作所需的一些信息,IP 地址和端口號就是典型的例子。
連接時還會分配緩存
連接操作中所交換的控制信息是根據通信規則來確定的,只要根據規則執行連接操作,雙方就可以得到必要的信息從而完成數據收發的準備。
此外,當執行數據收發操作時,我們還需要一塊用來臨時存放要收發的數據的內存空間,這塊內存空間稱為緩沖區,它也是在連接操作的過程中分配的。上面這些就是“連接”這個詞代表的具體含義。
2.2.2 負責保存控制信息的頭部
之前我們說的控制信息其實可以大體上分為兩類。
客戶端和服務器相互聯絡時交換的控制信息
這些信息不僅連接時需要,包括數據收發和斷開連接操作在內,整個通信過程中都需要,這些內容在 TCP 協議的規格中進行了定義。
具體來說,表 2.1 中的這些字段就是 TCP 規格中定義的控制信息。這些字段是固定的,在連接、收發、斷開等各個階段中,每次客戶端和服務器之間進行通信時,都需要提供這些控制信息。
如圖 2.4(a)所示,這些信息會被添加在客戶端與服務器之間傳遞的網絡包的開頭。
在連接階段,由於數據收發還沒有開始,所以如圖 2.4(b)所示,網絡包中沒有實際的數據,只有控制信息。
這些控制信息位於網絡包的開頭,因此被稱為頭部。
此外,以太網和 IP 協議也有自己的控制信息,這些信息也叫頭部,為了避免各種不同的頭部發生混淆,我們一般會記作 TCP 頭部、以太網頭部 、IP 頭部。
以太網頭部又稱“MAC 頭部”。
保存在套接字中用來控制協議棧操作的信息
應用程序傳遞來的信息以及從通信對象接收到的信息都會保存在這裏,收發數據操作的執行狀態等信息也會保存在這裏,協議棧會根據這些信息來執行每一步的操作。
套接字的控制信息和協議棧的程序本身其實是一體的,因此,“協議棧具體需要哪些信息”會根據協議棧本身的實現方式不同而不同。
因為協議棧中的控制信息通信對方是看不見的,只要在通信時按照規則將必要的信息寫入頭部,客戶端和服務器之間的通信就能夠得以成立。
不同系統的協議棧的實現不同,因此我們無法具體說明協議棧裏到底保存了哪些控制信息。
總結
通信操作中使用的控制信息分為兩類:
頭部中記錄的信息
接字(協議棧中的內存空間)中記錄的信息
2.2.3 連接操作的實際過程
我們已經了解了連接操作的含義,下面來看一下具體的操作過程。這個過程是從應用程序調用 Socket 庫的 connect 開始的。
connect(< 描述符 >, < 服務器 IP 地址和端口號 >, … )
上面的調用提供了服務器的 IP 地址和端口號,這些信息會傳遞給協議棧中的 TCP 模塊。
然後,TCP 模塊會與該 IP 地址對應的對象,也就是與服務器的 TCP 模塊交換控制信息,這一交互過程包括下面幾個步驟。
①客戶端創建TCP頭部
客戶端先創建一個包含表示開始數據收發操作的控制信息的頭部。如表 2.1 所示。頭部包含很多字段,這裏要關註的重點是發送方和接收方的端口號。
到這裏客戶端(發送方)的套接字就準確找到了服務器(接收方)的套接字,也就是搞清楚了我應該連接哪個套接字。
然後,我們將頭部中的控制位的 SYN 比特設置為 1,大家可以認為它表示連接。此外還需要設置適當的序號和窗口大小。
②客戶端將數據傳給服務器
當 TCP 頭部創建好之後,接下來 TCP 模塊會將信息傳遞給 IP 模塊並委托它進行發送。
IP 模塊執行網絡包發送操作後,網絡包就會通過網絡到達服務器,然後服務器上的 IP 模塊會將接收到的數據傳遞給 TCP 模塊,服務器的 TCP 模塊根據 TCP 頭部中的信息找到端口號對應的套接字。
也就是說,從處於等待連接狀態的套接字中找到與 TCP 頭部中記錄的端口號相同的套接字就可以了。
當找到對應的套接字之後,套接字中會寫入相應的信息,並將狀態改為正在連接。
③服務器創建TCP頭部,返回響應
上述操作完成後,服務器的 TCP 模塊會返回響應,這個過程和客戶端一樣,需要在 TCP 頭部中設置發送方和接收方端口號以及 SYN 比特
此外,在返回響應時還需要將 ACK 控制位設為1,這表示已經接收到相應的網絡包。
網絡中經常會發生錯誤,網絡包也會發生丟失,因此雙方在通信時必須相互確認網絡包是否已經送達,而設置ACK 比特就是用來進行這一確認的。
④服務器將數據傳給客戶端
接下來,服務器 TCP 模塊會將 TCP頭部傳遞給 IP 模塊,並委托 IP 模塊向客戶端返回響應。
然後,網絡包就會返回到客戶端,通過 IP 模塊到達 TCP 模塊,並通過 TCP 頭部的信息確認連接服務器的操作是否成功。
如果 SYN 為 1 則表示連接成功,這時會向套接字中寫入服務器的 IP 地址、端口號等信息,同時還會將狀態改為連接完畢。
到這裏,客戶端的操作就已經完成,但其實還剩下最後一個步驟。
⑤客戶端告訴服務器響應已收到
剛才服務器返回響應時將 ACK 比特設置為 1,相應地,客戶端也需要將 ACK 比特設置為 1 並發回服務器,告訴服務器剛才的響應包已經收到。
當這個服務器收到這個返回包之後,連接操作才算全部完成。
建立連接之後,協議棧的連接操作就結束了,也就是說 connect 已經執行完畢,控制流程被交回到應用程序。
網絡是怎樣連接的學習筆記-第二章-連接服務器