当前位置:网站首页>【網絡是怎樣連接的】第六章 請求到達服務器以及響應給客戶端(完結)
【網絡是怎樣連接的】第六章 請求到達服務器以及響應給客戶端(完結)
2022-07-02 17:37:00 【Currybeefer】
1.服務器架構
當網絡包到達Web服務器後,服務器就會接收這個包並進行處理。服務器有很多種類,其硬件和操作系統與客戶端相比是不一樣的。但是網絡相關的部分,如網卡,協議棧,Socket庫什麼的和客戶端卻別無二致。無論硬件還是OS如何變化,TCP和IP的功能都是一樣的。(當然Socket庫的用法以及服務器程序的結構還是不同的)
服務器的程序結構如圖,我們可以把程序分為兩個模塊,等待連接模塊a以及負責與客戶端通信的模塊b。
當服務器啟動的時候就會運行等待連接模塊a,這個模塊負責創建套接字,然後進入等待連接的暫停狀態。當客戶端發起連接時候,a模塊就會恢複運行並且接收連接,然後啟動通信模塊b,給b完成連接的套接字。然後b就會使用已連接的套接字與客戶端通信。每次有新客戶端連接,就會啟動一個b,因此客戶端和b是一對一的關系。
2.服務器建立連接的過程
接下來我們具體看服務器接受連接的過程。
首先a模塊在服務器程序啟動的時候就存在了,首先,協議棧會調用socket創建套接字,向套接字內寫入指定要使用的端口號。接下來,協議棧會調用listen向套接字寫入等待連接狀態這一控制信息,這樣套接字就進入等待連接狀態。然後協議棧就會調用accept來接受連接,然後馬上暫停程序運行。等待網絡包真正到達了,再繼續進程。
一旦客戶端包到達,程序就會返回相應包然後接受連接操作。A模塊會給等待連接的套接字複制一個副本,將客戶端套接字與這個副本連在一起。然後啟動b模塊,將副本交給b模塊。之後就進行數據收發操作了。
為什麼要複制一個套接字副本而不是直接將這個套接字交給b呢?因為如果不創建新的,則這個套接字交給b模塊後,就沒有套接字等待連接了,如果有其他客戶端發起連接就會遇到問題。
那麼既然套接字都是複制於一個母本,那麼這些套接字的端口號必然都是一樣的。那麼一個網絡包到達後,如果協議棧只看TCP頭部接收方端口號,就無法判斷要將包交給哪個套接字了。
解决方案就是,不僅僅只看接收方端口號,協議棧要通過客戶端IP地址,端口號,服務端IP地址,端口號來共同確定要把包交給哪個套接字。如圖所示
3. 服務器接收操作
5.
下面詳細敘述服務器接收網絡包的時候的操作,假定這是一個TCP網絡包。
MAC模塊
首先是網卡中的MAC模塊負責,網卡接收到信號後,根據報頭信號變化提取時鐘信號,然後利用這個時鐘信號還原數字信息。
接下來查看包末尾的幀校驗序列FCS來校驗是否錯誤,如果發現數據已經因為噪聲等影響導致信號失真,則丟弃該網絡包。
當FCS校驗通過,此時檢查MAC頭部中的接收方MAC地址,看看這個包是不是發給自己的。
如果是自己的,就將信息保存在網卡的緩沖區中,調用中斷,讓CPU來處理接收到的網絡包。CPU根據MAC頭部的以太類型字段判斷協議種類,這裏,一臺類型的值錶示IP協議,因此會調用TCP/IP協議棧,並將包轉交給它。
IP模塊
然後就到IP模塊開始工作。IP模塊會檢查IP頭部格式是否規範,然後看看接收方IP地址是不是寫著自己。當服務器有類似路由器的包轉發功能時,對於不是自己的包也會向路由器那樣根據路由錶對包轉發。
如果是自己,接下來檢查包有沒有被分片(分片的話IP報頭會有個標志),如果分片了就暫存在內存中,等分片全部到達再一起組裝起來。然後檢查IP頭部的協議號字段,發現是TCP協議,則轉交給TCP字段處理。
TCP模塊
如果TCP頭部的SYN為1,錶示這是一個發起連接的包,這是TCP模塊會檢查TCP報頭中接收方的端口號,確認有沒有相同端口號並且在等待連接的套接字。如果沒有則向客戶端返回包含錯誤通知的包。
如果有套接字,則為這個套接字複制一個副本,然後將發送方的IP地址,端口號,序列號初始值,窗口大小等必要參數寫入副本中,分配好用於發送緩沖區和接收緩沖區的內存空間。然後生成代錶接收確認的ACK號,用於從服務器發向客戶端數據的序號初始值,錶示接收緩沖區剩餘容量的窗口大小,並用這些信息生成TCP頭部,委托IP模塊發送給客戶端。
這個包到達客戶端後,客戶端會返回錶示接收確認的ACK號,當這個ACK號返回服務器後,連接操作就完成了。這是服務端程序應該進入調用accept的暫停狀態,當新套接字的描述符轉交給服務器程序後,服務器程序就會恢複運行。
如果TCP模塊此時接收的是一個數據包,則檢查IP模塊和TCP模塊中的雙方IP地址和端口號信息,然後找到這些信息全都匹配的套接字。然後根據這個套接字中保存的上一個的序號和數據長度計算應該接收到的包的序號,然後與TCP頭部的序號比對一番,看看有沒有丟包。如果一直,則TCP會從包中取出數據,放到接收緩沖區中,與緩沖區中上次收到的數據塊連接起來。
之後TCP會生成確認應答數據包,根據包序號和數據長度計算出ACK號,委托IP模塊發給客戶端。(在返回這個包之前,會先等一段時間,看看能不能和後續的應答包合並)
然後就是TCP模塊的斷開操作,具體參考之前寫的內容,非常詳細。這裏不再贅述。
5.服務器返回響應消息
當服務器完成對請求消息的各種處理之後,就可以返回響應消息了。這裏的工作過程和客戶端向服務器發送請求消息時的過程相同。
首先,Web服務器調用Socket庫的write,將響應消息交給協議棧。這時,需要告訴協議棧這個響應消息應該發給誰,但我們並不需要直接告知客戶端的IP地址等信息,而是只需要給出錶示通信使用的套接字的描述符就可以了。套接字中保存了所有的通信狀態,其中也包括通信對象的信息,因此只要有描述符就萬事大吉了。
接下來,協議棧會將數據拆分成多個網絡包,然後加上頭部發送出去。這些包中包含接收方客戶端的地址,它們將經過交換機和路由器的轉發,通過互聯網最終到達客戶端。
附上整個網絡包的旅程全圖
到這裏整本書的內容就結束了,我只是簡略概括書中的大致內容,也省略了一些我認為不必要的內容。這真是一本非常好的入門書籍,看完後我感覺對於計算機網絡的整個大框架都有了。接下來就應該去深入地啃一些書籍。
路漫漫其修遠兮,吾將上下而求索。
边栏推荐
- This "architect growth note" made 300 people successfully change jobs and enter the big factory, with an annual salary of 50W
- Explanation of traceroute command
- TCP拥塞控制详解 | 2. 背景
- JS20 数组扁平化
- ETH数据集下载及相关问题
- Sword finger offer 26 Substructure of tree
- [web technology] 1233 seconds understand web component
- RK1126平台项目总结
- VirtualLab基础实验教程-7.偏振(2)
- Vscode knowledge points - Common Errors
猜你喜欢
Si446 usage record (II): generate header files using wds3
LeetCode:1380. Lucky number in matrix -- simple
[非线性控制理论]7_High gain and High Frequency
Platform management background and merchant menu resource management: merchant role management design
About me
链表求和[dummy+尾插法+函数处理链表引用常见坑位]
Qstype implementation of self drawing interface project practice (II)
The construction of scalable distributed database cluster and the partition design of oneproxy sub database
ThreadLocal
关于我
随机推荐
SAP Commerce Cloud Storefront 框架选型:Accelerator 还是 Spartacus?
ROS knowledge point - message_filters
详细介绍scrollIntoView()方法属性
How to create a new page for SAP Spartacus storefront
从收集到输出:盘点那些强大的知识管理工具——优秀笔记软件盘点(四)
Use of nexttile function in MATLAB
PCL知识点——体素化网格方法对点云进行下采样
常用SQL语句(完整范例)
Nexus Introduction and Xiaobai use idea Packaging and Upload to Nexus 3 private service detailed tutoriel
将您的基于 Accelerator 的 SAP Commerce Cloud Storefront 迁移到 Spartacus
ROS knowledge points -- the difference between ros:: nodehandle N and NH ("~")
HDU - 1114 Piggy-Bank(完全背包)
深度之眼(三)——矩阵的行列式
ssb门限_SSB调制「建议收藏」
Qwebengineview crash and alternatives
什么是敏捷开发流程
executescalar mysql_ExecuteScalar()
Microservice architecture practice: using Jenkins to realize automatic construction
The beginning of life
Sword finger offer 21 Adjust the array order so that odd numbers precede even numbers