網路程式設計 客戶 伺服器程式設計正規化

2022-01-29 17:01:19 字數 1694 閱讀 5349

迭代tcp伺服器總是在完全處理某個客戶的請求之後才開始下乙個客戶的請求處理

這樣的伺服器實際中比較少見。

基於udp的大多伺服器卻是這樣實現

傳統併發伺服器呼叫fork派生乙個子程序來處理每個客戶,這使得伺服器能夠同時為多個客戶服務,每個程序乙個客戶

客戶數目的唯一限制是作業系統對其能夠同時擁有多少子程序的限制。

絕大多數tcp伺服器程式都是按這個正規化編寫。

併發伺服器的問題在於為每個客戶現場fork乙個子程序比較耗費cpu時間。

不同於傳統意義的併發伺服器那樣為每個客戶現場派生乙個子程序,而是在啟動階段預先派生一定數量的子程序,當有客戶連線到達時,這些子程序就能立即為它提供服務

這種技術的有點在於無需引入父程序執行fork的開銷就能處理新到來的客戶。缺點是父程序必須在服務啟動階段猜測需要預先派生多少子程序。如果某個時刻客戶數恰好等於子程序總數,那麼新到的客戶將被忽略,直到至少有乙個子程序完成處理重新可用。

在多個程序中引用同乙個監聽套接字的描述符上呼叫accept的做法在某些系統實現是不被支援的,那麼解決辦法是讓應用程序在呼叫accept前後安裝某種形式的鎖(lock),這樣任意時刻只有乙個子程序阻塞在accept呼叫中,其他子程序則阻塞在獲取保護accept的鎖上。

這裡使用檔案鎖來保護,檔案鎖涉及到檔案系統的操作,可能比較耗時。

相比於預先派生子程序,使用檔案上鎖保護accept,使用執行緒鎖保護accept,這種方法不僅適用於同一程序內各個執行緒間的鎖保護,而且能夠用於不同程序之間的鎖保護

在不同程序間的鎖保護需要注意的是

只讓父程序嗲用accept,然後把所接受的已經連線的套接字傳遞給某個子程序。

這樣繞過了為所有子程序的accept呼叫提供上鎖保護的需求,但是需要從父程序到子程序進行某種形式的描述符傳遞。

這種技術會上**比較複雜,父程序必須跟蹤子程序的閒忙狀態,以便於給空閒的子程序傳遞新的套接字。

相比於多程序模型,如果伺服器主機提供支援執行緒,我們可以改用執行緒以取代程序。執行緒相比於程序的優勢這裡不再累述。

相比預先派生乙個子程序池快於為每個客戶執行緒fork乙個子程序池類似的道理,在有執行緒支援的系統上,預先建立的執行緒池取代為每個客戶現場建立乙個執行緒的做法有類似的效能提公升。

這種模式的基本設計是預先建立乙個執行緒,並讓每個執行緒各自呼叫accept,取代讓每個執行緒都阻塞在accept呼叫中的做法,使用互斥鎖保證任何時刻只有乙個執行緒在呼叫accept。

程式啟動階段建立乙個執行緒池後讓主線程呼叫accept;

主線程把每個客戶連線傳遞給池中某個可用的執行緒,類似於程序版本的做法。

這樣的設計問題在於主線程如何將乙個已連線套接字傳遞給執行緒池中某個可用執行緒

我們有很多實現手段,本可用如前面一樣使用描述符傳遞,但是既然所有執行緒和所有描述符都在同乙個程序中,那麼也就沒有必要把乙個描述符從乙個執行緒傳遞到另乙個執行緒。接收執行緒只需要知道這個已連線套接字描述符的值(傳遞描述符可不只是傳遞這個值,事實上是需要傳遞這個套接字的引用,因此也將返回乙個不同於原值的描述符,該套接字的引用計數也會增加

客戶 伺服器程式設計正規化

本篇從基於tcp ip協議出發,現代流行的應對高併發請求網路服務端設計架構 1.tcp ip 模型 首先回顧一下tcp ip模型,並知道各個層次在作業系統的哪乙個層次 看上圖,osi模型的底下兩層是隨系統提供的裝置驅動程式和網路硬體。通常情況下,除需知道資料鏈路的某些特性外,我們不用關心這兩層的情況...

客戶 伺服器程式設計正規化

unix 網路程式設計第30章讀書筆記,這裡只記錄大致實現方式,具體 實現還請閱讀此書 tcp 迭代伺服器 完全同步方式,完全處理某個客戶的請求之後才專向下乙個客戶,優點是 簡單,並且沒有程序控制所需的時間 tcp 併發伺服器程式,每個客戶乙個子程序 傳統上併發伺服器呼叫fork 派生乙個子程序來處...

主題 客戶 伺服器程式設計正規化

原文出處 本篇從基於tcp ip協議出發,現代流行的應對高併發請求網路服務端設計架構 1.tcp ip 模型 看上圖,osi模型的底下兩層是隨系統提供的裝置驅動程式和網路硬體。通常情況下,除需知道資料鏈路的某些特性外,我們不用關心這兩層的情況。網路層由ipv4和ipv6兩個協議處理,可以選擇的傳輸層...