谈谈网络编程
我從事的是企業(yè)級(jí)的軟件開(kāi)發(fā),縱觀當(dāng)今的企業(yè)級(jí)軟件,單機(jī)模型已經(jīng)越來(lái)越少,更多的是C/S模型,目前client和server之間通信是通過(guò)socket技術(shù)來(lái)實(shí)現(xiàn)的。
上面提到了socket技術(shù),自然要學(xué)習(xí)TCP/IP協(xié)議,對(duì)于TCP/IP的理論,學(xué)習(xí)Richard的《TCP/IP詳解 卷1:協(xié)議》我認(rèn)為是不二的選擇,這本書涵蓋內(nèi)容很多,如果對(duì)于只是實(shí)現(xiàn)C/S通信的網(wǎng)絡(luò)庫(kù)而言,僅需要了解其中介紹UDP和TCP的章節(jié)就好,扎實(shí)的理論基礎(chǔ)會(huì)為你以后遇到網(wǎng)絡(luò)傳輸中出現(xiàn)的問(wèn)題給予很好的解釋,也便于你解決這些問(wèn)題。理論聯(lián)系實(shí)現(xiàn),還是Richard的《UNIX網(wǎng)絡(luò)編程 卷1:套接口API》(俗稱UNP1),這本書我一直在看,但是還沒(méi)看完,我認(rèn)為這是網(wǎng)絡(luò)編程的圣經(jīng),你掌握了這本書,基本也就掌握了網(wǎng)絡(luò)編程,甚至細(xì)枝末節(jié)也能覆蓋到。
(以下只涉及TCP協(xié)議)
? ??緊接著學(xué)習(xí)轉(zhuǎn)為實(shí)踐,想想網(wǎng)絡(luò)通信的場(chǎng)景:一個(gè)server要對(duì)應(yīng)成千上萬(wàn),甚至十萬(wàn)..個(gè)客戶,這樣必須要考慮到server的處理能力。
最簡(jiǎn)單的模型就是你用一個(gè)進(jìn)程來(lái)處理所有的客戶端連接,my god!你想想,在處理過(guò)程中如果有上百個(gè)連接同時(shí)請(qǐng)求服務(wù),我們采用這種模式,首先下一個(gè)連接要等著上一個(gè)連接處理完(同步),這個(gè)在處理的連接還很有可能阻塞在數(shù)據(jù)操作(I/O)上,這樣處理連接的效率之差及客戶端的響應(yīng)之慢我想幾乎沒(méi)有人能忍受吧。
好,為了提高效率,我們改進(jìn)一下,對(duì)每一個(gè)客戶連接產(chǎn)生一個(gè)線程(windows)或進(jìn)程(linux)來(lái)處理,拋開(kāi)線程或進(jìn)程的上下文切換損耗不談,也不談SMP,就單單看產(chǎn)生成千上百個(gè)線程和進(jìn)程的可行性,對(duì)不起,咱操作系統(tǒng)可是有線程或進(jìn)程資源上限的。
為了解決線程頻繁切換造成的資源損耗和資源數(shù)限制問(wèn)題,我們?cè)俑倪M(jìn)一下,采用一個(gè)線程池來(lái)處理部分連接,其他連接排隊(duì)等候,畢竟咱cpu不多,同時(shí)也就能處理那么幾個(gè)連接,響應(yīng)效率和處理效率依然提不上去。
想一個(gè)問(wèn)題,其實(shí)我們的網(wǎng)絡(luò)耗時(shí)一般都是在數(shù)據(jù)操作上(I/O),為了增加客戶端的響應(yīng),我們可以把一次網(wǎng)絡(luò)接入分為處理連接的線程和進(jìn)行邏輯處理的線程,這樣就可以極大地提高客戶端的響應(yīng),但是記住一定要在邏輯處理線程中維護(hù)住這個(gè)連接的會(huì)話。這樣仿佛還不錯(cuò),no,no,其實(shí)也不好,你并不知道什么時(shí)候有數(shù)據(jù)到來(lái)需要處理,你必須要輪詢來(lái)確定可不可以進(jìn)行數(shù)據(jù)操作....,效率還是不好啊。
好了,咱不自己獨(dú)創(chuàng)技術(shù)了,選用經(jīng)典的Reactor和Proactor并發(fā)編程模式,他們都是基于事件驅(qū)動(dòng)的,咱呢就是把網(wǎng)絡(luò)中需要處理的事件注冊(cè)到事件管理器中去(比如網(wǎng)絡(luò)行為事件,IO操作事件.....),然后等事件狀態(tài)就緒了,他就用回調(diào)的方式通知咱去處理,怎么樣,這樣至少CPU不會(huì)閑著了,只用一個(gè)線程就可以處理幾乎所有的事件了。但是Reactor和Proactor還是有很大區(qū)別的,Reactor對(duì)于I/O這一步是需要自己處理的,但是Proactor對(duì)于I/O這一步是由操作系統(tǒng)完成的,然后把完成事件通知你,然后你就可以進(jìn)行下一步操作了(比如從緩沖區(qū)buf里讀數(shù)據(jù)),比自己操作I/O這種方式快多了吧。目前,我在windows下寫網(wǎng)絡(luò)庫(kù)采用的是Proactor模式:用windows自己提供的完成端口模型(IOCP)實(shí)現(xiàn),在linux下,由于linux沒(méi)有很好的異步I/O機(jī)制,只好采用Reactor方式了:使用的是linux特有的epoll。談一些我自己的看法:從我的理解上,對(duì)于大部分網(wǎng)絡(luò)庫(kù)而言,很多都是I/O密集型的,這樣仿佛采用Proactor模式更有優(yōu)勢(shì),但是linux下沒(méi)有和windows下IOCP類似的機(jī)制,但是可以采用epoll加任務(wù)隊(duì)列的方式實(shí)現(xiàn)一套,但是仿佛很復(fù)雜,我想自己實(shí)現(xiàn)就算了吧。好在“山窮水復(fù)疑無(wú)路,柳暗花明又一村”,boost asio 已經(jīng)為我們封轉(zhuǎn)好了windows和linux下的Proactor實(shí)現(xiàn),windows采用的是完成端口,linux下采用的是epoll加任務(wù)隊(duì)列的方式實(shí)現(xiàn)。下一步我準(zhǔn)備把目前l(fā)inux下采用epoll方式實(shí)現(xiàn)的Reactor網(wǎng)絡(luò)庫(kù)改為boost asio的實(shí)現(xiàn)。
今天,對(duì)于網(wǎng)絡(luò)編程先總體并且概括的介紹下吧,其實(shí)還有很多問(wèn)題沒(méi)有涉及,我本人對(duì)網(wǎng)絡(luò)編程十分的感興趣,現(xiàn)在也在從事這方面的工作,所以以后有機(jī)會(huì)希望和大家一起分享一些更細(xì)致全面的知識(shí),鑒于本人水平有限,希望大家能對(duì)文章中出現(xiàn)的錯(cuò)誤給予批評(píng)指正,我們一起進(jìn)步......
總結(jié)
- 上一篇: TCP发送接口(如send(),writ
- 下一篇: 《TCP/IP详解:卷1》之TCP/UD