四川大學(xué)軟件學(xué)院 姚欽文
基于NoB2的網(wǎng)絡(luò)聊天室設(shè)計與簡單實現(xiàn)
四川大學(xué)軟件學(xué)院 姚欽文
針對現(xiàn)在一些網(wǎng)絡(luò)交互系統(tǒng)中因為網(wǎng)絡(luò)通訊模塊效率不高從而成為系統(tǒng)瓶頸的問題,利用boost庫設(shè)計并實現(xiàn)了一個異步的網(wǎng)絡(luò)構(gòu)件,該構(gòu)件包含TCP和UDP兩種傳輸協(xié)議,其中TCP包含斷線重連機制,因為boost.asio庫的高效異步傳輸機制,使得NoB2成為一個輕量、高效、跨平臺的網(wǎng)絡(luò)構(gòu)件,文章討論了緩沖區(qū)數(shù)量和傳輸速度的關(guān)系,并且在最后簡單實現(xiàn)了一個基于NoB2的網(wǎng)絡(luò)聊天室。
網(wǎng)絡(luò);網(wǎng)絡(luò)構(gòu)件;Boost;輕量級
NoB2(Network On Boost for second edition)是一個網(wǎng)絡(luò)庫,能夠給上層提供接口,讓上層能夠輕易基于本庫開發(fā)出一個含有網(wǎng)絡(luò)交互模塊的系統(tǒng),設(shè)計出該構(gòu)件的目的是讓業(yè)務(wù)邏輯層與應(yīng)用層分析,實現(xiàn)代碼的低耦合,使得系統(tǒng)具有擴展和修改性,并且具有很好的傳輸效率。
現(xiàn)在在市面上已經(jīng)呈現(xiàn)出很多網(wǎng)絡(luò)構(gòu)件。如:
①1WebService[1][2],一種構(gòu)建應(yīng)用程序的普遍模型,可以在任何支持網(wǎng)絡(luò)通信的操作系統(tǒng)中實施運行,它是一種新的web應(yīng)用程序分支,是自包含、自描述、模塊化的應(yīng)用,可以發(fā)布、定位、通過web調(diào)用。
②EJB[3][4]是sun的服務(wù)器端組件模型,設(shè)計目標(biāo)與核心應(yīng)用是部署分布式應(yīng)用程序。憑借java跨平臺的優(yōu)勢,用EJB技術(shù)部署的分布式系統(tǒng)可以不限于特定的平臺。
上面兩種都是著眼于企業(yè)級的大型應(yīng)用,用上面的構(gòu)建來實現(xiàn)一些我們?nèi)粘5男⌒途W(wǎng)絡(luò)交互系統(tǒng)是在不合適。目前在Boost.asio庫上已經(jīng)衍生出了Bas[5],OrzNet[6][7],muduo[8]等網(wǎng)絡(luò)應(yīng)用框架。
③Bas,bas為boost_asio_server(baserver)的簡稱,采用Half-Sync/Half-Async模式的服務(wù)器框架,使用c++實現(xiàn),能夠大大簡化tcpserver的開發(fā)工作。Bas更多的是側(cè)重于框架型的tcpserver方向。
④OrzNet,OrzNet是Open Esources Zone for network意思為網(wǎng)絡(luò)開放的資源空間,是一組高效、可擴展的跨平臺網(wǎng)絡(luò)程序開發(fā)工具集。
⑤muduo,是國人陳碩開發(fā)的一個庫,總的代碼不超過5000行,簡潔高效,不好的就是不考慮可移植性,不跨平臺,只支持Linux,不支持Windows,不支持UDP,只支持TCP,不支持IPv6,只支持IPv4。
Boost庫是一個可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的發(fā)動機之一。Boost庫由C++標(biāo)準(zhǔn)委員會庫工作組成員發(fā)起,其中有些內(nèi)容有望成為下一代C++標(biāo)準(zhǔn)庫內(nèi)容。在C++社區(qū)中影響甚大,是不折不扣的“準(zhǔn)”標(biāo)準(zhǔn)庫。Boost由于其對跨平臺的強調(diào),對標(biāo)準(zhǔn)C++的強調(diào),與編寫平臺無關(guān)。
①建立一個獨立的網(wǎng)絡(luò)構(gòu)件,以庫的形式開發(fā)出來。要足夠小,足夠輕量、要包含多種傳輸協(xié)議、包含完成的客戶端和服務(wù)器端。
②構(gòu)件不能是一個框架形式,因為要讓這個構(gòu)件來適應(yīng)使用者的業(yè)務(wù)邏輯,采用C++編程。
③做到最大限度的封裝,讓應(yīng)用層上層通過簡單的API調(diào)用就能建立連接并且隨意傳輸數(shù)據(jù),至于實現(xiàn)細(xì)節(jié),用戶不必知道。
④該庫要有緩沖區(qū)管理和錯誤處理類。
⑤對于TCP連接來說,要有斷線重連機制。
3.2.1 類設(shè)計
類介紹:
● Message:需要傳輸?shù)臄?shù)據(jù)的持有者
● Buffer:管理多個Message
● TCPConnection:一個客戶端連接對應(yīng)一個TCPConnection,數(shù)據(jù)傳輸主要通過該類完成
● ConnectionMap:管理Connection
● ServerErrorHandler:服務(wù)器錯誤處理類
● ClientErrorHandler:客戶端錯誤處理類
①Tcpserver,如圖1所示
● TCPServer有維護(hù)兩個Buffer,一個讀Buffer和一個寫B(tài)uffer,接收發(fā)送的message放在緩沖中
②Tcpclient
● TCPClient和TCPServer類似,只是不維護(hù)connectionMap,只有一個連接。
③Udpserver,如圖2所示
● UDPServer:由于UDP是無連接的協(xié)議,所以天生不需要維護(hù)客戶端的鏈接,因而沒有connectionMap,只需要記錄每個客戶端的地址就夠了,雖然UDP方式下面的Buffer類和TCP的Buffer類名相同,但是它們的實現(xiàn)完全不同,在不同的命名空間中。
④Udpclient端設(shè)計,如圖3所示
● UDPClient:同TCPClient
3.2.2 線程設(shè)計
NoB2采用了half-sync/half-async構(gòu)架模式,其實就是將異步請求排隊到一個同步隊列中,然后再從隊列中取出請求處理,其實就是一個擴大的生產(chǎn)者/消費者問題。在socket編程的關(guān)鍵在于,將業(yè)務(wù)邏輯操作和底層的io操作分散到不同的線程中,避免業(yè)務(wù)邏輯操作可能導(dǎo)致整個線程的堵塞。在所有客戶端和服務(wù)器端中都采用了這種構(gòu)架模式,主要是出于可讀性和效率方面的考慮,最大化的體現(xiàn)了半同步半異步架構(gòu)模式中“主從關(guān)系”的優(yōu)勢。
TCP方式中的斷線重連主要采用“心跳”機制,在客戶端和服務(wù)器都維護(hù)一個超時計數(shù),客戶端定期向服務(wù)器發(fā)送“心跳”脈沖,服務(wù)器接收脈沖,清零計數(shù),同時回復(fù)脈沖,客戶端接收脈沖后也清零計數(shù)??蛻舳藶椤靶奶睓C制新增三個線程,一個發(fā)送脈沖線程,一個增加計數(shù)線程,一個重連線程。
客戶端斷線檢測響應(yīng)在10S內(nèi),服務(wù)器斷線檢測響應(yīng)在30S內(nèi),當(dāng)然,這個時間可以調(diào)整。
TCPServer端除了上面檢測線程,還有一個監(jiān)聽線程,一個寫線程,多個讀線程,每個讀線程對應(yīng)一個tcp連接。
當(dāng)啟動一個TCPServer時,就同時啟動了監(jiān)聽、寫、檢測線程,監(jiān)聽線程用于監(jiān)聽TCP連接,當(dāng)TCP連接請求到達(dá)時,就新建一個讀線程,讀取該連接接收的消息,創(chuàng)建讀線程完成后,返回繼續(xù)監(jiān)聽。TCPClient端除了上面“心跳機制”線程,還有一個寫線程,一個讀線程。UDPServer端,由于不需要維護(hù)連接,因而只需要一個讀線程,一個寫線程。
UDPClient和UDPServer一樣。
①NoB2的輕量性:NoB2作為一個庫,而不是一個框架,總的代碼不超過3500行,功能符合基本需求,作為構(gòu)件組合到其他軟件中,是一個很簡單的事情,同時跨系統(tǒng),移植性非常強。
②NoB2的高效特性:由Boost.asio庫演化而來,建立在高效的asio庫上,使得NoB2的效率大大提高。asio庫最大亮點在于異步IO,異步IO的概念和同步IO相對,當(dāng)一個異步過程發(fā)出后,調(diào)用者通過回調(diào)函數(shù)可以得知任務(wù)的完成。就算使用者完全不懂socket編程,也可以通過使用NoB2編寫出優(yōu)秀簡潔的網(wǎng)絡(luò)應(yīng)用。
③緩沖大小對傳輸速率的影響:在本機TCP客戶端通過巡回地址向服務(wù)器傳輸一個136KB大小的ASCII碼文本文件,每次傳輸8個字節(jié),實驗結(jié)果如表1。
可以看出,緩沖區(qū)增加有助于提高程序速率。還可以看出,當(dāng)緩沖區(qū)數(shù)量增加到一定程度的時候,不會再提高速率,所以緩沖區(qū)數(shù)量要和程序消息流通量在一定的比例的時候,效率最高,也不會浪費資源。
通過上面對NoB2構(gòu)件的介紹,可以知道基于NoB2寫一個網(wǎng)絡(luò)多人聊天室是一個非常簡單的事情。
首先,聊天室使用TCP傳輸協(xié)議,需要服務(wù)器和多個客戶端來構(gòu)建,客戶端首先發(fā)消息給服務(wù)器,服務(wù)器收到后再給其他客戶端發(fā)送相同消息,來達(dá)到多人聊天的效果。
如圖4,客戶端連接服務(wù)器后,新建讀和寫線程就完成了客戶端的設(shè)置。
表1
如圖5,服務(wù)器每次讀一條消息,然后發(fā)給其他所有連接。
上面介紹了服務(wù)器和客戶端主要代碼,測試圖圖6中開了3個客戶端,可以看出,通過NoB2高度的封裝,使得應(yīng)用層使用該構(gòu)件開發(fā)網(wǎng)絡(luò)應(yīng)用軟件變得非常的簡單。
NoB2的高效封裝性,使得開發(fā)者在設(shè)計開發(fā)包含網(wǎng)絡(luò)應(yīng)用的程序中,可以不用再關(guān)心網(wǎng)絡(luò)模塊部分,把而把大量的時間投入到界面設(shè)計中,一個軟件的界面做的精美,能夠讓用戶體驗變得更好。
[1]R.Orfali,D.Harkey,J.Edwards.The Essential Client/Server Survival Guide[M].Robert譯.天下遠(yuǎn)見出版股份有限公司,1997.
[2]ACE[EB/OL].http://baike.baidu.com/view/139851.htm.
[3]R.Orfali,D.Harkey,J.Edwards:Instant Corba[M].John Wiley & Sons,Inc.,1997.
[4]EJB[EB/OL].http://baike.baidu.com/view/3542.htm.
[5]Sun Microsystems,Inc:RMI-Remote Method Invocation,Available at:http://www.javasoft.com/products/jdk/l.l/docs/guide/rmi,March 1998.
[6]C.Szyperski:Component Software[M].Addison Wesley Longman,Ltd.,1997.
[7]OrzNET[EB/OL].http://baike.baidu.com/view/6168709.htm.
[8]發(fā)布一個基于Reactor模式的C++網(wǎng)絡(luò)庫[EB/OL].http://blog.csdn.net/solstice/article/details/5848547.
[9]An Introduction to Boost.chm[M/OL].http://ishare.iask.sina.com.cn/f/17358057.html.
[10]boost_1_41_0_doc_20091225.chm[M/OL].http://code.google.com/p/sleepwomcpp/source/browse/ebook?r=910.
[11]The Boost C++Libraries.chm[M/OL].http://ishare.iask.sina.com.cn/f/12335487.html.
姚欽文(1991—),男,四川人,大學(xué)本科,現(xiàn)就讀于四川大學(xué),主要研究方向:計算機網(wǎng)絡(luò)、信息安全。