四川大學軟件學院 姚欽文
基于NoB2的網絡聊天室設計與簡單實現
四川大學軟件學院 姚欽文
針對現在一些網絡交互系統中因為網絡通訊模塊效率不高從而成為系統瓶頸的問題,利用boost庫設計并實現了一個異步的網絡構件,該構件包含TCP和UDP兩種傳輸協議,其中TCP包含斷線重連機制,因為boost.asio庫的高效異步傳輸機制,使得NoB2成為一個輕量、高效、跨平臺的網絡構件,文章討論了緩沖區數量和傳輸速度的關系,并且在最后簡單實現了一個基于NoB2的網絡聊天室。
網絡;網絡構件;Boost;輕量級
NoB2(Network On Boost for second edition)是一個網絡庫,能夠給上層提供接口,讓上層能夠輕易基于本庫開發出一個含有網絡交互模塊的系統,設計出該構件的目的是讓業務邏輯層與應用層分析,實現代碼的低耦合,使得系統具有擴展和修改性,并且具有很好的傳輸效率。
現在在市面上已經呈現出很多網絡構件。如:
①1WebService[1][2],一種構建應用程序的普遍模型,可以在任何支持網絡通信的操作系統中實施運行,它是一種新的web應用程序分支,是自包含、自描述、模塊化的應用,可以發布、定位、通過web調用。
②EJB[3][4]是sun的服務器端組件模型,設計目標與核心應用是部署分布式應用程序。憑借java跨平臺的優勢,用EJB技術部署的分布式系統可以不限于特定的平臺。
上面兩種都是著眼于企業級的大型應用,用上面的構建來實現一些我們日常的小型網絡交互系統是在不合適。目前在Boost.asio庫上已經衍生出了Bas[5],OrzNet[6][7],muduo[8]等網絡應用框架。
③Bas,bas為boost_asio_server(baserver)的簡稱,采用Half-Sync/Half-Async模式的服務器框架,使用c++實現,能夠大大簡化tcpserver的開發工作。Bas更多的是側重于框架型的tcpserver方向。
④OrzNet,OrzNet是Open Esources Zone for network意思為網絡開放的資源空間,是一組高效、可擴展的跨平臺網絡程序開發工具集。
⑤muduo,是國人陳碩開發的一個庫,總的代碼不超過5000行,簡潔高效,不好的就是不考慮可移植性,不跨平臺,只支持Linux,不支持Windows,不支持UDP,只支持TCP,不支持IPv6,只支持IPv4。
Boost庫是一個可移植、提供源代碼的C++庫,作為標準庫的后備,是C++標準化進程的發動機之一。Boost庫由C++標準委員會庫工作組成員發起,其中有些內容有望成為下一代C++標準庫內容。在C++社區中影響甚大,是不折不扣的“準”標準庫。Boost由于其對跨平臺的強調,對標準C++的強調,與編寫平臺無關。
①建立一個獨立的網絡構件,以庫的形式開發出來。要足夠小,足夠輕量、要包含多種傳輸協議、包含完成的客戶端和服務器端。
②構件不能是一個框架形式,因為要讓這個構件來適應使用者的業務邏輯,采用C++編程。
③做到最大限度的封裝,讓應用層上層通過簡單的API調用就能建立連接并且隨意傳輸數據,至于實現細節,用戶不必知道。
④該庫要有緩沖區管理和錯誤處理類。
⑤對于TCP連接來說,要有斷線重連機制。
3.2.1 類設計
類介紹:
● Message:需要傳輸的數據的持有者
● Buffer:管理多個Message
● TCPConnection:一個客戶端連接對應一個TCPConnection,數據傳輸主要通過該類完成
● ConnectionMap:管理Connection
● ServerErrorHandler:服務器錯誤處理類
● ClientErrorHandler:客戶端錯誤處理類
①Tcpserver,如圖1所示
● TCPServer有維護兩個Buffer,一個讀Buffer和一個寫Buffer,接收發送的message放在緩沖中
②Tcpclient
● TCPClient和TCPServer類似,只是不維護connectionMap,只有一個連接。
③Udpserver,如圖2所示
● UDPServer:由于UDP是無連接的協議,所以天生不需要維護客戶端的鏈接,因而沒有connectionMap,只需要記錄每個客戶端的地址就夠了,雖然UDP方式下面的Buffer類和TCP的Buffer類名相同,但是它們的實現完全不同,在不同的命名空間中。
④Udpclient端設計,如圖3所示
● UDPClient:同TCPClient
3.2.2 線程設計
NoB2采用了half-sync/half-async構架模式,其實就是將異步請求排隊到一個同步隊列中,然后再從隊列中取出請求處理,其實就是一個擴大的生產者/消費者問題。在socket編程的關鍵在于,將業務邏輯操作和底層的io操作分散到不同的線程中,避免業務邏輯操作可能導致整個線程的堵塞。在所有客戶端和服務器端中都采用了這種構架模式,主要是出于可讀性和效率方面的考慮,最大化的體現了半同步半異步架構模式中“主從關系”的優勢。

TCP方式中的斷線重連主要采用“心跳”機制,在客戶端和服務器都維護一個超時計數,客戶端定期向服務器發送“心跳”脈沖,服務器接收脈沖,清零計數,同時回復脈沖,客戶端接收脈沖后也清零計數??蛻舳藶椤靶奶睓C制新增三個線程,一個發送脈沖線程,一個增加計數線程,一個重連線程。
客戶端斷線檢測響應在10S內,服務器斷線檢測響應在30S內,當然,這個時間可以調整。
TCPServer端除了上面檢測線程,還有一個監聽線程,一個寫線程,多個讀線程,每個讀線程對應一個tcp連接。
當啟動一個TCPServer時,就同時啟動了監聽、寫、檢測線程,監聽線程用于監聽TCP連接,當TCP連接請求到達時,就新建一個讀線程,讀取該連接接收的消息,創建讀線程完成后,返回繼續監聽。TCPClient端除了上面“心跳機制”線程,還有一個寫線程,一個讀線程。UDPServer端,由于不需要維護連接,因而只需要一個讀線程,一個寫線程。
UDPClient和UDPServer一樣。
①NoB2的輕量性:NoB2作為一個庫,而不是一個框架,總的代碼不超過3500行,功能符合基本需求,作為構件組合到其他軟件中,是一個很簡單的事情,同時跨系統,移植性非常強。
②NoB2的高效特性:由Boost.asio庫演化而來,建立在高效的asio庫上,使得NoB2的效率大大提高。asio庫最大亮點在于異步IO,異步IO的概念和同步IO相對,當一個異步過程發出后,調用者通過回調函數可以得知任務的完成。就算使用者完全不懂socket編程,也可以通過使用NoB2編寫出優秀簡潔的網絡應用。
③緩沖大小對傳輸速率的影響:在本機TCP客戶端通過巡回地址向服務器傳輸一個136KB大小的ASCII碼文本文件,每次傳輸8個字節,實驗結果如表1。
可以看出,緩沖區增加有助于提高程序速率。還可以看出,當緩沖區數量增加到一定程度的時候,不會再提高速率,所以緩沖區數量要和程序消息流通量在一定的比例的時候,效率最高,也不會浪費資源。
通過上面對NoB2構件的介紹,可以知道基于NoB2寫一個網絡多人聊天室是一個非常簡單的事情。
首先,聊天室使用TCP傳輸協議,需要服務器和多個客戶端來構建,客戶端首先發消息給服務器,服務器收到后再給其他客戶端發送相同消息,來達到多人聊天的效果。
如圖4,客戶端連接服務器后,新建讀和寫線程就完成了客戶端的設置。

表1
如圖5,服務器每次讀一條消息,然后發給其他所有連接。
上面介紹了服務器和客戶端主要代碼,測試圖圖6中開了3個客戶端,可以看出,通過NoB2高度的封裝,使得應用層使用該構件開發網絡應用軟件變得非常的簡單。
NoB2的高效封裝性,使得開發者在設計開發包含網絡應用的程序中,可以不用再關心網絡模塊部分,把而把大量的時間投入到界面設計中,一個軟件的界面做的精美,能夠讓用戶體驗變得更好。
[1]R.Orfali,D.Harkey,J.Edwards.The Essential Client/Server Survival Guide[M].Robert譯.天下遠見出版股份有限公司,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]發布一個基于Reactor模式的C++網絡庫[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—),男,四川人,大學本科,現就讀于四川大學,主要研究方向:計算機網絡、信息安全。