Socket服務(wù)器框架_第1頁
Socket服務(wù)器框架_第2頁
Socket服務(wù)器框架_第3頁
Socket服務(wù)器框架_第4頁
Socket服務(wù)器框架_第5頁
已閱讀5頁,還剩12頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、可擴展多線程異步Socket服務(wù)器框架EMTASS 2.0 0 前言>>前言、第1節(jié)、第2節(jié)、第3節(jié)、第4節(jié)、第5節(jié)、第6節(jié)在程序設(shè)計與實際應(yīng)用中,Socket數(shù)據(jù)包接收服務(wù)器夠得上一個經(jīng)典問題了:需要計算機與網(wǎng)絡(luò)編程知識(主要是Socket),與業(yè)務(wù)處理邏輯密切(如:包組成規(guī)則),同時還要兼顧系統(tǒng)運行的穩(wěn)定、效率、安全與管理等。具體應(yīng)用時,在滿足業(yè)務(wù)處理邏輯要求的基礎(chǔ)上,存在側(cè)重點:有些需要考慮并發(fā)與效率,有些需要強調(diào)穩(wěn)定與可靠等等。雖然.NET 2.0 Framework上的IOCP(I/O完成端口)異步技術(shù)可以有效解決并發(fā)等問題,但完全的異步模式也缺乏一些控制上的靈活性,例如

2、:Socket暫停操作等。 本文介紹的是一個傳統(tǒng)Socket數(shù)據(jù)包服務(wù)器解決方案,該方案改自筆者2005年底的一個交通部省級公路交通流量數(shù)據(jù)服務(wù)器中心(DSC)項目。當時.NET Framework 2.0 與 Visual Studio 2005 發(fā)布沒多久,筆者接觸C#的時間不長。于是Google了國內(nèi)國外網(wǎng),希望找點應(yīng)用C#解決Socket通信問題的思路和代碼。最后,找到了兩篇幫助最大的文章:一篇是國人2005年3月寫的Socket接收器框架在C#中使用異步Socket編程實現(xiàn)TCP網(wǎng)絡(luò)服務(wù)的C/S的通訊構(gòu)架(一)(分(一)、(二)兩篇),該文應(yīng)用了客戶端Socket會話(Session

3、)概念;另一篇是美國人寫的,提出了多線程、分段接收數(shù)據(jù)包的技術(shù)方案,描述了多線程、異步Socket的許多實現(xiàn)細節(jié),該文堅定了筆者采用多線程和異步方式處理Socket接收器的技術(shù)路線。第一個版本EMTASS 1.0(EMTASS,Extensible Multi-Thread Asynchronous Socket Server)于2006年初完成并投入使用。 今年暑假,筆者修改了原Socket接收服務(wù)器代碼,即EMTASS 1.1。最近,又按框架的可擴展性、可重用性等要求重新構(gòu)思和設(shè)計了EMTASS,即EMTASS 2.0。下面的介紹共分六個部分: 1. 總體思路與架構(gòu) 2. 關(guān)鍵實現(xiàn)技術(shù) 3

4、. 框架使用簡介 4. 一般測試結(jié)果 5. 總結(jié)與展望 6. 版本與源碼 1 總體思路與架構(gòu)>>前言、第1節(jié)、第2節(jié)、第3節(jié)、第4節(jié)、第5節(jié)、第6節(jié)1.1 總體思路總體構(gòu)思上,主要考慮多線程、異步Socket和可擴展性三個方面。 1) 三個核心線程在Internet環(huán)境下的Socket應(yīng)用中,客戶端和網(wǎng)絡(luò)容易出現(xiàn)異常,此時必須釋放異常退出的Socket資源??紤]到服務(wù)器的高并發(fā)能力,一般采取包接收和處理分開的策略:將接收到的包添加到包隊列,然后處理隊列中的數(shù)據(jù)包。當然,偵聽遠程客戶端的連接請求可以用Socket的AcceptAsync()異步方法(IOCP,I/O完成端口由此開始)

5、??紤]到暫停、關(guān)閉同步操作,仍然用一個線程。這樣,清理資源、處理數(shù)據(jù)包、偵??蛻暨B接請求就是組成了EMTASS架構(gòu)的三個核心線程,它們由.NET線程池統(tǒng)一管理: 1. 客戶端連接偵聽線程 StartServerListen():循環(huán)偵聽遠程客戶端的Socket連接請求。如果存在,通過適當規(guī)范性判斷后創(chuàng)建該Socket的客戶端會話TSessionBase對象(實際上是該類的派生類對象),同時調(diào)用該會話對象的Socket異步數(shù)據(jù)接收方法BeginReceive(),接收到的數(shù)據(jù)包存放在會話對象的包隊列中。當然,新增的TSessionBase對象將添加到會話隊列m_sessionTable(一個Di

6、ctionary<>泛型對象)中,該隊列表就是清理和處理線程的遍歷對象; 2. 數(shù)據(jù)包處理線程 CheckDatagramQueue():循環(huán)檢測TSessonBase隊列中的會話對象,調(diào)用該對象的相關(guān)方法完成數(shù)據(jù)包解析、判斷類型、數(shù)據(jù)存儲等任務(wù); 3. 會話表檢測線程 CheckSessionTable():循環(huán)檢查會話表m_sessionTable中的各個會話對象,分步驟清理已經(jīng)超時、無效或異常的會話對象,清理會話對象的緩沖區(qū),釋放其Socket資源。 2) 異步處理模式.NET Framework中的Socket具有完整的異步處理能力:偵聽后異步接收(AcceptAsync(

7、))、數(shù)據(jù)異步接收(BeginReceive())、數(shù)據(jù)異步發(fā)送(BeginSend())等。EMTASS框架采取了異步接收和發(fā)送方式,并封裝在TSessionBase類中。在EMTASS的版本1.0、1.1中,這些方法在主類TSocketServerBase中實現(xiàn),顯然不符合類封裝原則。 3) 系統(tǒng)可擴展性可擴展性主要考慮不同的業(yè)務(wù)處理邏輯和應(yīng)用場景,即:數(shù)據(jù)包格式、數(shù)據(jù)存儲方法、數(shù)據(jù)庫服務(wù)器等。框架EMTASS的可擴展性體現(xiàn)在類的泛型與抽象設(shè)計、方法虛擬和保護等方面: · 抽象類:會話基類TSessionBase、數(shù)據(jù)庫基類TDatabaseBase均是抽象類,分別提供了數(shù)據(jù)包分

8、析與判斷、數(shù)據(jù)存儲的虛擬方法; · 泛型類:主要基類TSocketServerBase有TSessionBase、TDatabaseBase兩個泛型約束參數(shù),可以根據(jù)這兩個抽象類的派生類產(chǎn)生具體的服務(wù)器類型; · 方法抽象(abstract):TSessionBase的數(shù)據(jù)包分析方法AnalyzeDatagram()、TDatabaseBase的數(shù)據(jù)庫打開方法Open()均是抽象的,必須在派生類中根據(jù)業(yè)務(wù)處理邏輯和數(shù)據(jù)庫類型重寫; · 方法保護(protected):與事件處理有關(guān)的方法、與業(yè)務(wù)處理邏輯相關(guān)的方法全部是protected方法,可以根據(jù)實際情況重寫。

9、 1.2 類架構(gòu)1)主要類層次結(jié)構(gòu)(圖1 主要類層次關(guān)系) 按應(yīng)用類別分,EMTASS主要有四組類:Socket服務(wù)器類、Session會話類、Database數(shù)據(jù)庫類和枚舉類型。 · Socket服務(wù)器類 o 服務(wù)器泛型類 TSocketServerBase:該類包括了一個服務(wù)器Socket對象、一個TDatabaseBase派生類對象、一個會話TSessionBase類派生對象的列表(Dictionary<>泛型對象),封裝了TDatabaseBase、TSessionBase的全部事件,提供統(tǒng)一的對外公開接口和事件; o 泛型參數(shù):服務(wù)器基類TSocketServe

10、rBase有兩個泛型參數(shù):TSessionBase類和TDatabaseBase類,定制它們的派生類后可以確定泛型類的具體版本。 · 客戶端會話類 o 會話核心成員類 TSessionCoreInfo:是TSessionBase的基類,包括會話的核心字段:登錄時間、最近會話時間、IP地址、客戶端名、對象狀態(tài)等,是會話列表清單和事件參數(shù)的基類之一。該類的成員字段全部是protected的,需要在派生類中賦予具體值; o 抽象會話類 TSessionBase:封裝了客戶端Socket、數(shù)據(jù)接收緩沖區(qū)、數(shù)據(jù)包緩沖區(qū)、數(shù)據(jù)包隊列等數(shù)據(jù)結(jié)構(gòu),包括了與客戶端通信相關(guān)的全部方法:數(shù)據(jù)接收與發(fā)送、數(shù)

11、據(jù)包處理等。 · 數(shù)據(jù)庫類 o 抽象數(shù)據(jù)庫基類 TDatabaseBase:封裝了數(shù)據(jù)庫打開與關(guān)閉、異常事件處理等方法,其中數(shù)據(jù)連接屬性DbConnection是虛屬性、數(shù)據(jù)庫打開方法Open()是抽象方法,需要在派生類中重寫; o 基類TSqlServerBase:派生自TDatabaseBase,應(yīng)用System.Data.SqlClient名稱空間中SqlServer相關(guān)類型重定義了數(shù)據(jù)庫連接屬性DbConnection、重寫了Open()方法; o 基類TOleDbDatabaseBase:派生自TDatabaseBase,應(yīng)用System.Data.OleDb名稱空間中Ol

12、eDb數(shù)據(jù)訪問相關(guān)類型重定義了基類的連接屬性DbConnection、重寫了Open()方法 · 枚舉類型 o 會話狀態(tài)類型 TSessioinState:取4個值:Valid、Invalid、Shutdown和Closed。為Valid時表示會話是有效的,為Invalid時表示會話將被清理,為Shutdown時表示會話Socket正在卸載,為Closed時表示會話已經(jīng)關(guān)閉、資源已經(jīng)清理; o 會話斷開類型 TDisconnectType:取3個值:Normal、Timeout和Exception,分別表示正常連接、超時斷開、異常斷開。其中,超時表示最近兩次會話接收數(shù)據(jù)的時間超過約定

13、的時限,防止某些會話長時間占有資源。 2)事件參數(shù)類型結(jié)構(gòu)圖(圖2 事件參數(shù)類層次關(guān)系) EMTASS框架的事件包括三類:第一,普通事件,如:服務(wù)器啟動與停止;第二,異常事件,接收與發(fā)送數(shù)據(jù)異常、數(shù)據(jù)庫連接或數(shù)據(jù)存儲異常等;第三,與會話相關(guān)事件,如:增加會話對象、接收到一個合法數(shù)據(jù)包等。異常與會話結(jié)合即是會話異常事件。通過泛型委托EventHandler可以定義類事件,其中的事件參數(shù)類型如下: · 異常事件參數(shù)類 TExceptionEventArgs:封裝了異常Exception對象的Message值; · 會話事件參數(shù)類 TSessionEventArgs:封裝了一個T

14、SessionCoreInfo對象; · 會話異常參數(shù)類 TSessionExceptionEventArgs:派生自TSessionEventArgs,包括異常消息字段Message。 2 關(guān)鍵實現(xiàn)技術(shù)>>前言、第1節(jié)、第2節(jié)、第3節(jié)、第4節(jié)、第5節(jié)、第6節(jié)下面介紹主要類TSocketServerBase和輔助類TSessionBase、TDatabaseBase中的主要實現(xiàn)方法。 2.1 TSocketServerBase類該類包括了全部的對外接口和事件,主要實現(xiàn)前面介紹過的三個線程。 1) 線程池與同步信號.NET 提供了線程池方法 ThreadPool.Queue

15、UserWorkItem() 自動將委托對象添加到系統(tǒng)線程池,見如下的實現(xiàn)代碼: if (!ThreadPool.QueueUserWorkItem(this.StartServerListen) return false; if (!ThreadPool.QueueUserWorkItem(this.CheckDatagramQueue) return false; if (!ThreadPool.QueueUserWorkItem(this.CheckSessionTable) return false;其中, 客戶端連接請求偵聽方法StartServerListen()、數(shù)據(jù)包隊列檢查方

16、法CheckDatagramQueue()和會話表檢查方法CheckSessionTable()均使用循環(huán)處理方式,循環(huán)條件是m_serverClosed為false。只有該類的Close()方法可以中斷這三個線程。在Close()方法中設(shè)置m_serverClosed為true終止線程的同時,還需要考慮線程退出的同步問題,此時使用手工事件信號對象ManualResetEvent。參考如下數(shù)據(jù)包隊列檢查線程方法的代碼: private void CheckDatagramQueue(object state) m_checkDatagramQueueResetEvent.Reset(); wh

17、ile (!m_serverClosed) lock (m_sessionDictionary) / .其它代碼 m_checkDatagramQueueResetEvent.Set();上述代碼是不安全的,一般要需要tryfinally保證事件信號對象Reset()與Set()匹配。但EMTASS中的三個線程方法均有自己的異常處理方式,不會拋出異常。下面是關(guān)閉服務(wù)器方法Close()的主要代碼。在設(shè)置變量了m_serverCloed為true后,使用了三個事件信號等待,同步三個線程的正常終止。 private void Close() if (m_serverClosed) return;

18、m_serverClosed = true; m_serverListenPaused = true; m_checkServerListenResetEvent.WaitOne(); / 等待3個線程 m_checkSessionTableResetEvent.WaitOne(); m_checkDatagramQueueResetEvent.WaitOne(); / .其它代碼2) 分步驟的清理線程建立會話對象后,三種情況需要終止會話:1)關(guān)閉服務(wù)器;2)會話異常;3)會話超時。第1種情況將強制終止會話,第2、3種情況需要清理線程終止會話并釋放其資源。為防止立即關(guān)閉Socket引發(fā)的異常,

19、系統(tǒng)分3個步驟完成:1)標記該會話為Invalid,此時停止一切與該會話的處理操作;2)調(diào)用Shutdown()方法:Shutdown會話Socket,標記會話狀態(tài)為Shutdown;3)調(diào)用Close()方法:清除會話緩沖區(qū)和數(shù)據(jù)包隊列,釋放Socket資源,從會話表中刪除該對象。具體操作可以參考TSocketServerBase類中的CheckSessionTable()方法。 3) 事件傳遞與發(fā)布EMTASS框架的所有事件,包括TSessionBase類和TDatabaseBase類的事件,都通過服務(wù)器類TSocketServerBase對外發(fā)布。在創(chuàng)建會話對象或數(shù)據(jù)庫對象時,直接傳遞其

20、事件給TSocketServerBase的相同委托事件,見如下代碼舉例: session.DatagramAccepted += new EventHandler(this.OnDatagramAccepted); session.DatagramHandled += new EventHandler(this.OnDatagramHandled);上述代碼中,將TSessionBase派生類對象session的兩個事件直接綁定(使用+=方法)到當前TSocketServerBase對象上。具體實現(xiàn)代碼可以參考TSocketServerBase的初始化方法Initiate()和添加會話對象方法

21、AddSession()。 2.2 TSessionBase類該抽象類包括客戶端Socket、數(shù)據(jù)接收緩沖區(qū)和數(shù)據(jù)包隊列等成員,封裝了所有與Socket通信的方法。該類還包括數(shù)據(jù)包處理方法:數(shù)據(jù)包解析保護方法ResolveSessionBuffer()和數(shù)據(jù)包分析虛擬方法AnalyzeDatagram()。 1) 會話緩沖區(qū)和數(shù)據(jù)包隊列TSessionBase包括兩個數(shù)據(jù)接收緩沖區(qū)和一個數(shù)據(jù)包隊列: · m_receiveBuffer緩沖區(qū):接收客戶端Socket數(shù)據(jù)的緩沖區(qū),如果數(shù)據(jù)包比該緩沖區(qū)長,Socket將自動(異步)讀取幾次,每次用方法CopyToDatagramBuffe

22、r暫到數(shù)據(jù)包緩沖區(qū)m_datagramBuffer中; · m_datagramBuffer緩沖區(qū):如果m_receiveBuffer接收了非完整的數(shù)據(jù)包,則使用該緩沖區(qū)暫存,直到獲得一個完整數(shù)據(jù)包。一般情況下,設(shè)置m_receiveBuffer大于數(shù)據(jù)包長度,則一次可以接收一個完整包,此時該緩沖區(qū)為空。此外,該緩沖區(qū)大小根據(jù)數(shù)據(jù)包的長度動態(tài)增長; · m_datagramQueue包隊列:字節(jié)數(shù)組的隊列(Queue<>泛型),保存了當前會話的數(shù)據(jù)包(字節(jié)數(shù)組),等待處理線程分析與處理。在EMTASS 1.0與1.1中,該隊列結(jié)構(gòu)封裝在TSocketServer

23、Base內(nèi)。這種設(shè)計增加了TSessionBase類與TSocketServerBase類的偶合程度。 2) 數(shù)據(jù)包解析方法ResolveSessionBuffer()該方法是protected的,可以根據(jù)數(shù)據(jù)包結(jié)構(gòu)與具體業(yè)務(wù)邏輯重寫代碼。在TSessionBase類中實現(xiàn)的包組成規(guī)則是:開始字符是<結(jié)束字符是>。特別指出,Socket通信中有兩個必須考慮的著名問題: · 數(shù)據(jù)包界限問題:數(shù)據(jù)包字符串(字節(jié)數(shù)組)如何界限?在交通部的Socket通信協(xié)議中,用<>分別作為一個包的開始與結(jié)束字符; · 數(shù)據(jù)包間斷與重疊問題:由于網(wǎng)絡(luò)或設(shè)備故障,一個數(shù)據(jù)包

24、可能分兩次接收。另一種情況就是連續(xù)接收到多個數(shù)據(jù)包。第一種情況,需要先緩存接收到的包直到一個完整的數(shù)據(jù)包。第二種情況,則需要根據(jù)包界限符號分解一個個的包。 3) 數(shù)據(jù)包分析方法AnalyzeDatagram()該抽象方法是TSessionBase類必須重寫的方法,也是EMTASS框架擴展的主要接口,應(yīng)該完成如下基本任務(wù): · 判斷數(shù)據(jù)包的有效性與包類型; · 分解包中的各字段數(shù)據(jù); · 校驗包及其數(shù)據(jù)有效性; · 發(fā)送確認消息給客戶端(調(diào)用方法 SendDatagram(); · 存儲包數(shù)據(jù)到數(shù)據(jù)庫中; · 如果數(shù)據(jù)包中存在客戶端名稱

25、或編號,則填寫m_name字段。 2.3 TDatabaseBase類該抽象類定義了3個數(shù)據(jù)庫異常處理事件:DatabaseOpenException、DatabaseCloseExeption和DatabaseException,以及4個public方法:Open()、Close()、Clear()和Store()。其中,Open()是抽象方法,在派生類中可以增加自己的代碼(見demo的實現(xiàn)部分),Close()方法關(guān)閉數(shù)據(jù)庫連接,Clear()方法在Close()中被調(diào)用關(guān)閉數(shù)據(jù)庫前清理相關(guān)資源,虛方法Store()用于數(shù)據(jù)存儲。EMTASS框架給出了該基類的兩個派生類:TSqlServe

26、rBase和TOleDatabaseBase,可以滿足一般的數(shù)據(jù)庫應(yīng)用需求。 3 架構(gòu)使用簡介>>前言、第1節(jié)、第2節(jié)、第3節(jié)、第4節(jié)、第5節(jié)、第6節(jié)3.1 一般步驟EMTASS框架的使用包括如下步驟: · 定制滿足需求的TSqlServerBase或TOleDatabaseBase派生類 o 增加成員字段,如:DbCommand、DbDataAdapter等; o 重寫TDatabaseBase類的虛擬方法Store(),編寫保存數(shù)據(jù)包到數(shù)據(jù)庫中的實現(xiàn)代碼; o 在TSessionBase的AnalyzeDatagram()方法中直接或間接調(diào)用Store()方法。 &#

27、183; 定制滿足業(yè)務(wù)處理邏輯的TSessionBase派生類 o 重寫ResolveSessionBuffer()方法,按照數(shù)據(jù)包規(guī)則提取緩沖區(qū)中的數(shù)據(jù)包文,并存儲到包隊列中; o 重寫AnalyzeDatagram()方法,按前面的要求增加功能。 · 定制滿足需求的TSocketServerBase派生類 o 定義TSocketSErverBase泛型類的派生類(該步可省略); o 創(chuàng)建泛型類的派生類對象,在構(gòu)造函數(shù)中給出數(shù)據(jù)庫連接字符串和TCP通信端口; o 設(shè)置泛型類的派生類對象的最大數(shù)據(jù)包長度等參數(shù); o 實現(xiàn)泛型類的派生類對象的相關(guān)事件處理方法。 3.2 TSocketS

28、erverBase的構(gòu)造、屬性、方法和事件泛型類TSocketServerBase提供了EMTASS框架的所有對外接口(屬性、方法和事件),包括內(nèi)聯(lián)TSessionBase對象和TDatabaseBase對象的對外屬性和事件。 1) TSocketServerBase構(gòu)造函數(shù)有兩個重載版本,默認端口3130。考慮到可擴展性,必須給出數(shù)據(jù)庫連接串,見如下代碼: public TSocketServerBase(string dbConnectionString) this.Initiate(dbConnectionString);public TSocketServerBase(int tcpP

29、ort, string dbConnectionString) m_servertPort = tcpPort; this.Initiate(dbConnectionString);構(gòu)造函數(shù)中的方法Initiate()完成具體的初始化任務(wù)。 2) TSocketServerBase公共屬性· ServerPort:服務(wù)器端口號,默認值為3130 · Closed:服務(wù)器已經(jīng)關(guān)閉 · ListenPaused:服務(wù)器暫時停止客戶端連接請求 · LoopWaitTime:Socket.Listen方法中的等待時間(ms),默認值為25ms · Ma

30、xDatagramSize:允許數(shù)據(jù)包的最大長度,默認值為1024K · MaxListenQueueLength:最大偵聽隊列長度,默認值為16 · MaxReceiveBufferSize:允許數(shù)據(jù)包接收緩沖區(qū)的最大長度,默認值為16K · MaxSameIPCount:允許同地址IP的會話Socket個數(shù),默認值為64 · MaxSessionTableLength:允許最大會話表長度,默認值為1024 · MaxSessionTimeout:允許最大的會話超時間隔(s),默認值為120s · ErrorDatagramCoun

31、t:錯誤數(shù)據(jù)包個數(shù) · ReceivedDatagramCount:接收數(shù)據(jù)包個數(shù) · ServerExceptionCount:服務(wù)器異常次數(shù) · SessionCount:當前會話個數(shù) · SessionExeptionCount:會話異常個數(shù) · SessionCoreInfoList:當前會話表信息清單 3) TSocketServerBase公共方法· Start():啟動服務(wù)器 · Stop():關(guān)閉服務(wù)器 · PauseListen():暫停偵聽連接請求 · ResumeListen():恢

32、復偵聽連接請求 · Dispose():關(guān)閉服務(wù)器并釋放系統(tǒng)資源 · CloseSession():關(guān)閉一個會話 · CloseAllSessions():關(guān)閉全部會話 · SendToSession():給一個會話發(fā)送消息 · SendToAllSessions():給所有會話發(fā)送消息 4) TSocketServerBase事件· DatabaseCloseException:數(shù)據(jù)庫關(guān)閉異常 · DatabaseException:數(shù)據(jù)庫異常 · DatabaseOpenException:數(shù)據(jù)庫打開異常 &#

33、183; DatagramAccepted:接受了一個完整數(shù)據(jù)包 · DatagramDelimiterError:數(shù)據(jù)包界限符錯誤 · DatagramError:數(shù)據(jù)包錯誤 · DatagramHandled:處理了一個數(shù)據(jù)包 · DatagramOversizeError:數(shù)據(jù)包超長錯誤 · ServerStarted:服務(wù)器啟動后 · ServerClosed:服務(wù)器關(guān)閉后 · ServerListenPaused:服務(wù)器暫停連接請求后 · ServerListenResumed:服務(wù)器恢復連接請求后 &#

34、183; ServerException:服務(wù)器異常 · SessionRejected:連接請求被拒絕 · SessionConnected:建立一個會話連接 · SessionDisConnected:斷開一個會話連接 · SessionReceiveException:會話接收數(shù)據(jù)異常 · SessionSendException:會話發(fā)送數(shù)據(jù)異常 · SessionTimeout:會話超時 3.3 下載包Demo介紹下載包中包括EMTASS框源代碼和Demo。其中,VS2005的Demo解決方案文件為EMTASS.sln,包含

35、兩個項目:服務(wù)器項目和客戶端項目。/bin/文件夾下的編譯文件可直接運行:先啟動服務(wù)器,然后運行客戶端。 1) 服務(wù)器端Demo服務(wù)器端包括兩個部分:第一,接收服務(wù)器窗體程序;第二,Access數(shù)據(jù)庫。服務(wù)器端窗體程序包含如下實現(xiàn): · TSessionBase派生類TTestSession:重寫了OnDatagramDelimiterError()和OnDatagramOversizeError()事件處理方法,重寫了數(shù)據(jù)包分析方法AnalyzeDatagram(),增加了一個自定義方法Store(); · TDatabaseBase派生類TAccessDatabase:

36、增加了一個OleDbCommmand字段m_command,重寫了Open()方法和Store()方法。在重寫的Open()方法中,創(chuàng)建了m_command對象及其參數(shù)對象,給出了數(shù)據(jù)庫的Insert語句SQL代碼。重寫的Store()方法中,將TSessionBase的IP、SessionName和數(shù)據(jù)包長度保存到Access數(shù)據(jù)庫中。方法Store()將被TTestSession()的AnalyzeDatagram()方法調(diào)用; · TSocketServerBase<>對象:給出數(shù)據(jù)庫連接字符串后,應(yīng)用前面定義的兩個派生類創(chuàng)建泛型類對象,然后注冊該對象的事件實現(xiàn)方法

37、。注冊的事件方法功能包括:顯示服務(wù)器的如果計數(shù)情況,顯示服務(wù)器運行狀態(tài)。 服務(wù)器端的主要代碼如下: public partial class SocketServerDemo : Form TSocketServerBase m_socketServer; public SocketServerDemo() InitializeComponent(); private void SocketServerDemo_Load(object sender, EventArgs e) cb_maxDatagramSize.SelectedIndex = 1; / 數(shù)據(jù)庫連接字符串 string con

38、nStr = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source = DemoAccessDatabase.mdb;" m_socketServer = new TSocketServerBase(connStr); / 服務(wù)器對象 m_socketServer.MaxDatagramSize = 1024 * int.Parse(cb_maxDatagramSize.Text); / 包最大長度 this.AttachServerEvent(); / 附加服務(wù)器全部事件 private void SocketServerDemo_

39、FormClosing(object sender, FormClosingEventArgs e) m_socketServer.Dispose(); / 關(guān)閉服務(wù)器進程 private void AttachServerEvent() m_socketServer.ServerStarted += this.SocketServer_Started; m_socketServer.ServerClosed += this.SocketServer_Stoped; m_socketServer.ServerListenPaused += this.SocketServer_Paused; m

40、_socketServer.ServerListenResumed += this.SocketServer_Resumed; m_socketServer.ServerException += this.SocketServer_Exception; m_socketServer.SessionRejected += this.SocketServer_SessionRejected; m_socketServer.SessionConnected += this.SocketServer_SessionConnected; m_socketServer.SessionDisconnecte

41、d += this.SocketServer_SessionDisconnected; m_socketServer.SessionReceiveException += this.SocketServer_SessionReceiveException; m_socketServer.SessionSendException += this.SocketServer_SessionSendException; m_socketServer.DatagramDelimiterError += this.SocketServer_DatagramDelimiterError; m_socketS

42、erver.DatagramOversizeError += this.SocketServer_DatagramOversizeError; m_socketServer.DatagramAccepted += this.SocketServer_DatagramReceived; m_socketServer.DatagramError += this.SocketServer_DatagramrError; m_socketServer.DatagramHandled += this.SocketServer_DatagramHandled; m_socketServer.Databas

43、eOpenException += this.SocketServer_DatabaseOpenException; m_socketServer.DatabaseCloseExcpetion += this.SocketServer_DatabaseCloseException; m_socketServer.DatabaseExcpetion += this.SocketServer_DatabaseException; m_socketServer.ShowDebugMessage += this.SocketServer_ShowDebugMessage; /.其它代碼下面是服務(wù)器端D

44、emo運行圖片 2) 客戶端Demo創(chuàng)建一個TcpClient對象,模擬遠程客戶端與服務(wù)器通信。下面是客戶端Demo運行圖片: 4 一般測試結(jié)果>>前言、第1節(jié)、第2節(jié)、第3節(jié)、第4節(jié)、第5節(jié)、第6節(jié)· 機器配置:雙核CPU E2140,主頻1.6G,RAM是1G(含顯卡內(nèi)存)。 · 正確性測試 o 測試方法:客戶端的數(shù)據(jù)包含有長度串,在服務(wù)器端檢測比較,以此判斷數(shù)據(jù)包傳輸?shù)恼_性; o 測試情況:單機啟動服務(wù)器,運行7個客戶端程序,其中3個是干擾源連續(xù)做連接/斷開操作,另4個連續(xù)發(fā)送數(shù)據(jù)包。運行約80分鐘檢查,服務(wù)器平均每秒接收15個包,沒有發(fā)生異常,也沒有錯

45、誤包,數(shù)據(jù)包隊列穩(wěn)定在3以下。 · 速度測試 o 測試方法:單機運行服務(wù)器,然后運行20個客戶端程序,用10-50ms的速度發(fā)送數(shù)據(jù)包; o 測試情況:運行30分鐘檢查,服務(wù)器平均每秒接收60個包,沒有出現(xiàn)數(shù)據(jù)包隊列顯著增長等情況。 · 穩(wěn)定性測試:客戶端Demo中包含一個連接后馬上斷開的連續(xù)操作,在這種情況下服務(wù)器端沒有發(fā)現(xiàn)異常。此外,筆者在30個客戶端會話情況下運行服務(wù)器1個小時,沒有發(fā)生服務(wù)器端異常,但有個別客戶端異常退出。 · 并發(fā)性測試:同時運行了30個客戶端Demo,沒有發(fā)生服務(wù)器異常等現(xiàn)象,數(shù)據(jù)包隊列上限也不超過5。 · 測試結(jié)論: 在一臺

46、機器上做測試, EMTASS 2.0接收與處理正確,每秒可以處理60以上的數(shù)據(jù)包,運行穩(wěn)定可靠,有較好的并發(fā)處理能力。測試中發(fā)現(xiàn)的主要問題如下: o CPU占用率很大:顯然是三個線程的循環(huán)操作所引起的,在EMTASS1.0、1.1中,使用Thread.Sleep(m_waitTime)等待一段時間。本框架的設(shè)計目的是專用Socket服務(wù)器,為提高吞吐能力省略了這個操作。如果必要,在以后版本中添加該功能; o 服務(wù)器啟動后拒絕連接請求:特別是關(guān)閉后再啟動容易發(fā)生這種現(xiàn)象,多關(guān)閉啟動幾次后卻又恢復正常。筆者估計是服務(wù)器m_serverSocket對象釋放資源不同步的原因; o 客戶端連接請求被拒絕:有時客戶端發(fā)生錯誤后,再連接時被拒絕。有兩種可能

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論