談談網絡編程(基於C++)

這裏講了一點網絡編程的一些新路,一點體悟。學習就是這種不斷總結提升的過程。react

設計到進程,線程,線程池,reactior和proactor併發編程模式,IOCP,linux下的epoll。。。。。linux

講到這裏就要提一下 socket 技術了,要想理解socket天然要學習 TCP/IP 協議,對於 TCP/IP 的理論,學習 Richard 的《TCP/IP 詳解卷1:協議》我認爲是不二的選擇,這本書涵蓋內容不少,若是對於只是實現C/S通訊的網絡庫而言,僅須要瞭解其中介紹 UDP 和 TCP 的章節就好,紮實的理論基礎會爲你之後遇到網絡傳輸中出現的問題給予很好的解釋,也便於你解決這些問題。理論聯繫實現,仍是 Richard 的《UNIX 網絡編程卷1:套接口 API》(俗稱 UNP1),這本書我一直在看,可是還沒看完,我認爲這是網絡編程的聖經,你掌握了這本書,基本也就掌握了網絡編程,甚至細枝末節也能覆蓋到。這邊也推薦幾個視頻給你們看看。。。。c++

TCP/IP協議棧深度解析丨實現單機百萬鏈接丨優化三次握手、四次揮手丨優化TCP的傳輸速率丨epoll原理剖析和麪試必問的問題_嗶哩嗶哩 (゜-゜)つロ 乾杯~-bilibili​www.bilibili.com圖標c/c++Linux實戰訓練精講丨徒手實現網絡協議棧丨TCP/IP協議棧丨面試必備系列_嗶哩嗶哩 (゜-゜)つロ 乾杯~-bilibili​www.bilibili.com圖標面試

如下只涉及 TCP 協議編程

  緊接着學習轉爲實踐,想一想網絡通訊的場景:一個 server 要對應成百上千..個客戶,這樣必需要考慮到 server 的處理能力。windows

  最簡單的模型就是你用一個進程來處理全部的客戶端鏈接,my god!你想一想,在處理過程當中若是有上百個鏈接同時請求服務,咱們採用這種模式,首先下一個鏈接要等着上一個鏈接處理完(同步),這個在處理的鏈接還頗有可能阻塞在數據操做(I/O)上,這樣處理鏈接的效率之差及客戶端的響應之慢我想幾乎沒有人能忍受吧。網絡

  好,爲了提升效率,咱們改進一下,對每個客戶鏈接產生一個線程(windows)或進程(linux)來處理,拋開線程或進程的上下文切換損耗不談,也不談 SMP,就單單看產生成千上百個線程和進程的可行性,對不起,咱操做系統但是有線程或進程資源上限的。併發

  爲了解決線程頻繁切換形成的資源損耗和資源數限制問題,咱們再改進一下,採用一個線程池來處理部分鏈接,其餘鏈接排隊等候,畢竟咱 cpu 很少,同時也就能處理那麼幾個鏈接,響應效率和處理效率依然提不上去。異步

  想一個問題,其實咱們的網絡耗時通常都是在數據操做上(I/O),爲了增長客戶端的響應,咱們能夠把一次網絡接入分爲處理鏈接的線程和進行邏輯處理的線程,這樣就能夠極大地提升客戶端的響應,可是記住必定要在邏輯處理線程中維護住這個鏈接的會話。這樣彷彿還不錯,no,no,其實也很差,你並不知道何時有數據到來須要處理,你必需要輪詢來肯定可不能夠進行數據操做….,效率仍是很差啊。socket

  好了,咱不本身首創技術了,選用經典的 Reactor 和 Proactor 併發編程模式,他們都是基於事件驅動的,咱呢就是把網絡中須要處理的事件註冊到事件管理器中去(好比網絡行爲事件,IO 操做事件…..),而後等事件狀態就緒了,他就用回調的方式通知咱去處理,怎麼樣,這樣至少 CPU 不會閒着了,只用一個線程就能夠處理幾乎全部的事件了。可是 Reactor 和 Proactor 仍是有很大區別的,Reactor 對於I/O這一步是須要本身處理的,可是 Proactor 對於I/O這一步是由操做系統完成的,而後把完成事件通知你,而後你就能夠進行下一步操做了(好比從緩衝區 buf 裏讀數據),比本身操做I/O這種方式快多了吧。目前,我在 windows 下寫網絡庫採用的是 Proactor 模式:用 windows 本身提供的完成端口模型(IOCP)實現,在 linux 下,因爲 linux 沒有很好的異步I/O機制,只好採用 Reactor 方式了:使用的是 linux 特有的 epoll。

  談一些我本身的見解:從個人理解上,對於大部分網絡庫而言,不少都是I/O密集型的,這樣彷彿採用 Proactor 模式更有優點,可是 linux 下沒有和 windows 下 IOCP 相似的機制,可是能夠採用 epoll 加任務隊列的方式實現一套,可是彷彿很複雜,我想本身實現就算了吧。好在「山窮水復疑無路,柳暗花明又一村」,boost asio 已經爲咱們封轉好了 windows 和 linux 下的 Proactor 實現,windows 採用的是完成端口,linux 下采用的是 epoll 加任務隊列的方式實現。下一步我準備把目前 linux 下采用 epoll 方式實現的 Reactor 網絡庫改成 boost asio 的實現。

今天,對於網絡編程先整體而且歸納的介紹下吧,其實還有不少問題沒有涉及,我本人對網絡編程十分的感興趣,如今也在從事這方面的工做,因此之後有機會但願和你們一塊兒分享一些更細緻全面的知識,鑑於本人水平有限,但願你們能對文章中出現的錯誤給予批評指正,咱們一塊兒進步……
image.png須要以上資料能夠加qun:832218493免費領取!

相關文章
相關標籤/搜索