談談網絡編程(基于C++語言)

jopen 12年前發布 | 24K 次閱讀 C/C++

本文針對的是 Windows、Linux 下基于 C++ 語言的網絡編程

        我從事的是企業級的軟件開發,縱觀當今的企業級軟件,單機模型已經越來越少,更多的是C/S模型,目前 client 和 server 之間通信是通過 socket 技術來實現的。

        上面提到了 socket 技術,自然要學習 TCP/IP 協議,對于 TCP/IP 的理論,學習 Richard 的《TCP/IP 詳解卷1:協議》 我認為是不二的選擇,這本書涵蓋內容很多,如果對于只是實現C/S通信的網絡庫而言,僅需要了解其中介紹 UDP 和 TCP 的章節就好,扎實的理論基礎會為你以后遇到網絡傳輸中出現的問題給予很好的解釋,也便于你解決這些問題。理論聯系實現,還是 Richard 的《UNIX 網絡編程卷1:套接口 API》(俗稱 UNP1),這本書我一直在看,但是還沒看完,我認為這是網絡編程的圣經,你掌握了這本書,基本也就掌握了網絡編程,甚至細枝末節也能覆蓋到。

談談網絡編程(基于C++語言)

        以下只涉及 TCP 協議

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

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

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

        為了解決線程頻繁切換造成的資源損耗和資源數限制問題,我們再改進一下,采用一個線程池來處理部分連接,其他連接排隊等候,畢竟咱 cpu 不多,同時也就能處理那么幾個連接,響應效率和處理效率依然提不上去。

        想一個問題,其實我們的網絡耗時一般都是在數據操作上(I/O),為了增加客戶端的響應,我們可以把一次網絡接入分為處理連接的線程和進行邏輯 處理的線程,這樣就可以極大地提高客戶端的響應,但是記住一定要在邏輯處理線程中維護住這個連接的會話。這樣仿佛還不錯,no,no,其實也不好,你并不 知道什么時候有數據到來需要處理,你必須要輪詢來確定可不可以進行數據操作….,效率還是不好啊。

        好了,咱不自己獨創技術了,選用經典的 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 的實現。

        今天,對于網絡編程先總體并且概括的介紹下吧,其實還有很多問題沒有涉及,我本人對網絡編程十分的感興趣,現在也在從事這方面的工作,所以以后 有機會希望和大家一起分享一些更細致全面的知識,鑒于本人水平有限,希望大家能對文章中出現的錯誤給予批評指正,我們一起進步……

來自: 51CTO

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!