曾憲權(quán),肜 瑤
(1.許昌學(xué)院 信息工程學(xué)院,河南 許昌 461000;2.黃河科技學(xué)院 信息工程學(xué)院,河南 鄭州 450063)
隨著計算機(jī)和無線通信技術(shù)的發(fā)展,采用Internet與無線通信技術(shù)相結(jié)合構(gòu)建的新型無線遠(yuǎn)程監(jiān)控系統(tǒng)已經(jīng)廣泛地應(yīng)用到工業(yè)、交通、公安、電力和水利等行業(yè),成為現(xiàn)代安防系統(tǒng)的一個重要分支[1].在無線遠(yuǎn)程監(jiān)控系統(tǒng)中,通信服務(wù)器是系統(tǒng)的核心部件,負(fù)責(zé)接收遠(yuǎn)程監(jiān)控終端上傳的數(shù)據(jù),并對接收的數(shù)據(jù)進(jìn)行解析、處理后存入數(shù)據(jù)庫,或者轉(zhuǎn)發(fā)應(yīng)用系統(tǒng)發(fā)送的終端控制指令以便調(diào)整終端的工作狀態(tài),其設(shè)計的優(yōu)劣直接影響整個系統(tǒng)的性能.
對于如何構(gòu)建通信服務(wù)器,周欽強(qiáng)[2]等采用動態(tài)線程池技術(shù)來解決線程創(chuàng)建中的時間延遲,并根據(jù)客戶端數(shù)量的變化動態(tài)調(diào)整線程池中線程的數(shù)量.樹愛兵等[3]利用IOCP設(shè)計和實現(xiàn)了通信服務(wù)器,用于交通控制系統(tǒng)中的路口信號機(jī)、監(jiān)控終端及其控制軟件的數(shù)據(jù)通信及處理.原倉周等[4]針對遠(yuǎn)程車輛監(jiān)控系統(tǒng)遠(yuǎn)程終端數(shù)量多,通信頻繁的特點(diǎn),綜合利用Socket和多線程技術(shù)實現(xiàn)了大規(guī)模車輛監(jiān)控系統(tǒng)的通信服務(wù)器,實現(xiàn)了遠(yuǎn)程終端與服務(wù)器之間的交互.這些通信服務(wù)器基本上都采用了Socket通信和多線程技術(shù)來實現(xiàn).隨著客戶數(shù)量的增加,系統(tǒng)中的線程和Socket的數(shù)量會顯著增加,從而導(dǎo)致系統(tǒng)資源匱乏,系統(tǒng)性能下降.另一方面,隨著線程數(shù)量的增加,線程之間的同步和管理也會越來越復(fù)雜,從而影響了系統(tǒng)的性能.為了解決這些問題,利用.NET2.0及其以上類庫中的SocketAsyncEventArgs類設(shè)計和實現(xiàn)了一個高性能的通信服務(wù)器,采用異步調(diào)用.NET Socket類中的方法和連接池技術(shù)來提高服務(wù)器的性能,支持大規(guī)模客戶端的并發(fā)訪問,實現(xiàn)無阻塞的輸入和輸出.
一個典型的無線遠(yuǎn)程監(jiān)控系統(tǒng)通常由數(shù)據(jù)采集層、數(shù)據(jù)傳輸層、數(shù)據(jù)中心和應(yīng)用系統(tǒng)組成,其邏輯模型如圖1所示.
圖1 無線遠(yuǎn)程監(jiān)控系統(tǒng)邏輯模型Fig.1 Logical model of wireless remote monitoring system
數(shù)據(jù)采集層利用現(xiàn)場的終端設(shè)備采集監(jiān)控現(xiàn)場信息,通過無線通信模塊將信息上傳到數(shù)據(jù)中心的通信服務(wù)器,也可以接收來自監(jiān)控系統(tǒng)的控制命令并采取相應(yīng)的動作.
數(shù)據(jù)傳輸層是數(shù)據(jù)采集終端與數(shù)據(jù)中心的通信服務(wù)器以及應(yīng)用系統(tǒng)進(jìn)行數(shù)據(jù)通信的通道,利用公共無線通信網(wǎng)絡(luò)(如GPRS/CDMA等)和Internet網(wǎng)絡(luò)實現(xiàn)遠(yuǎn)程終端設(shè)備與數(shù)據(jù)中心的數(shù)據(jù)交互[5].
數(shù)據(jù)中心是遠(yuǎn)程無線監(jiān)控系統(tǒng)的數(shù)據(jù)共享中心,由通信服務(wù)器、數(shù)據(jù)庫服務(wù)器和應(yīng)用服務(wù)器組成.通信服務(wù)器是Internet網(wǎng)絡(luò)上具有固定IP的計算機(jī),它負(fù)責(zé)接收數(shù)據(jù)采集終端上傳的數(shù)據(jù),按照約定的協(xié)議解析后存入數(shù)據(jù)庫.通信服務(wù)器也可以將監(jiān)控系統(tǒng)發(fā)送的控制命令轉(zhuǎn)發(fā)到遠(yuǎn)程終端以控制遠(yuǎn)程終端的行為.應(yīng)用服務(wù)器根據(jù)客戶端請求從數(shù)據(jù)庫服務(wù)器讀取數(shù)據(jù)庫,進(jìn)行相應(yīng)的處理后,按照應(yīng)用系統(tǒng)的要求以表格、圖形或文字的形式將結(jié)果顯示在監(jiān)控系統(tǒng)的客戶計算機(jī)上,從而實現(xiàn)數(shù)據(jù)采集終端和監(jiān)控系統(tǒng)的信息交互.
應(yīng)用系統(tǒng)是遠(yuǎn)程無線監(jiān)控系統(tǒng)的客戶端,通常采用B/S框架結(jié)構(gòu),利用各種瀏覽器訪問應(yīng)用服務(wù)器中的程序,獲取遠(yuǎn)程終端設(shè)備傳送的數(shù)據(jù)[6],及時了解監(jiān)控現(xiàn)場的信息或者向遠(yuǎn)程終端設(shè)備發(fā)送控制命令.
在無線遠(yuǎn)程監(jiān)控系統(tǒng)中,通信服務(wù)器是各種數(shù)據(jù)的中轉(zhuǎn)站,是一個支持多連接長時間的實時通訊服務(wù)器[7],其主要功能如下:(1)建立通訊端口,監(jiān)聽遠(yuǎn)程終端發(fā)送的連接請求;(2)建立連接通道,從Internet網(wǎng)絡(luò)上接收遠(yuǎn)程監(jiān)控終端發(fā)送的數(shù)據(jù),按照約定的協(xié)議對接收的數(shù)據(jù)進(jìn)行解析,將解析后的原始數(shù)據(jù)存入數(shù)據(jù)庫.(3) 轉(zhuǎn)發(fā)監(jiān)控系統(tǒng)發(fā)送的控制命令到遠(yuǎn)程終端設(shè)備,以控制遠(yuǎn)程終端的數(shù)據(jù)讀取或參數(shù)設(shè)置,實現(xiàn)遠(yuǎn)程終端與監(jiān)控系統(tǒng)的交互.
根據(jù)通信服務(wù)器的功能和網(wǎng)絡(luò)通信的特點(diǎn),通信服務(wù)器從功能上可分為用戶界面、服務(wù)器管理、數(shù)據(jù)解析和處理、DTU(Data Transfer Unit)管理和數(shù)據(jù)訪問等幾個功能模塊.
(1)用戶界面負(fù)責(zé)初始化DTU隊列,啟動服務(wù)器,顯示在線DTU的信息.
(2)服務(wù)器管理模塊是通信服務(wù)器程序的核心,用于創(chuàng)建連接、接收和發(fā)送消息以及關(guān)閉連接,其性能是整個通信服務(wù)器程序的瓶頸.在設(shè)計時,采用了以下技術(shù)來提高服務(wù)器性能.①利用緩沖池來管理消息緩沖區(qū),實現(xiàn)緩沖區(qū)的重用,減少內(nèi)存碎片;②建立2個SocketAsyncEventArgs對象,一個用于接收消息,一個用于發(fā)送消息,實現(xiàn)雙工通信,提高通信效率;③利用接池技術(shù),實現(xiàn)了SocketAsyncEventArgs對象的復(fù)用,減少了時空開銷;④定時掃描連接對象,清除超時的連接對象,釋放其占用的資源.
(3)數(shù)據(jù)解析和處理模塊完成消息的接收和處理.服務(wù)器在接收到消息后,首先對接收的消息進(jìn)行準(zhǔn)確性驗證,以防止出現(xiàn)半個數(shù)據(jù)包造成的丟包現(xiàn)象,然后按照約定的協(xié)議對消息進(jìn)行解析,按照消息的類型存入相應(yīng)的數(shù)據(jù)表.
(4)數(shù)據(jù)訪問模塊利用數(shù)據(jù)庫連接工具將驗證后的數(shù)據(jù)寫入數(shù)據(jù)庫.該模塊首先利用ADO.NET建立連接池,然后根據(jù)需要對數(shù)據(jù)庫進(jìn)行讀寫操作.
(5)DTU管理模塊記錄在線的遠(yuǎn)程終端的信息,以便于進(jìn)行設(shè)備識別和消息發(fā)送.
根據(jù)無線遠(yuǎn)程監(jiān)控系統(tǒng)的通信特點(diǎn),設(shè)計了如表1所示的通信協(xié)議,以便有效處理異步通信中的TCP/IP消息無邊界問題,保證數(shù)據(jù)的可靠性.
表1 系統(tǒng)數(shù)據(jù)報文格式Tab.1 Format of system message
說明:1. 消息頭和消息尾:用來標(biāo)識消息的開始和結(jié)束位置.為了避免與消息內(nèi)容相混淆,消息頭和消息尾分別采用字符串“<<<”和“>>>”;2. 類型域:用來區(qū)分消息的類型,用一個字符表示.消息可分為設(shè)備注冊0x31、數(shù)據(jù)0x32、命令0x33和心跳包0x34等幾種類型;3. DTU編碼:用來標(biāo)識遠(yuǎn)程終端設(shè)備,用18個字符表示,每個DTU有唯一的編碼;4. 內(nèi)容域:發(fā)送的消息的內(nèi)容,長度不限,其具體內(nèi)容由消息類型決定.如果是注冊包,該區(qū)域內(nèi)容為空.
為了減少線程阻塞,提高通信服務(wù)的I/O性能,無線遠(yuǎn)程監(jiān)控系統(tǒng)的通信服務(wù)器采用了異步編程模型AMP[8](Asynchronous Programming Model),利用.NET 提供的SocketAsyncEventArgs 類[9]的方法來異步接收客戶端數(shù)據(jù),使用緩沖池和連接池來提高系統(tǒng)的效率,支持大量的客戶并發(fā)訪問.下面對系統(tǒng)實現(xiàn)的主要類做詳細(xì)說明.
SocketAsyncEventArgsPool類是連接池類,主要為服務(wù)器提供可用的用戶連接,并且維持這個連接直到用戶斷開,把空閑的連接對象放回連接池供下一個用戶連接重用.該類的主要方法如下:
(1) SocketAsyncEventArgsPool(int capacity):類的構(gòu)造函數(shù),參數(shù)為連接池中連接對象的數(shù)量.
(2)void Push (SocketAsyncEventArgs item):將空閑的連接對象放回連接池,實現(xiàn)連接對象的復(fù)用.
(3)SocketAsyncEventArgs Pop():該方法從連接池中獲取可用連接,開始進(jìn)行數(shù)據(jù)接收.
BufferManager類用來管理連接緩沖區(qū),為每一個連接維持一個接收數(shù)據(jù)的區(qū)域,以減少內(nèi)存碎片,提高內(nèi)存利用率.該類的主要方法如下:
(1)void InitBuffer() :該方法用于設(shè)置緩沖池的容量.
(2)bool SetBuffer(SocketAsyncEventArgs args):該方法為連接對象args分配接收緩沖區(qū),用來緩存客戶端發(fā)送來的消息.
(3) void FreeBuffer(SocketAsyncEventArgs args):該方法釋放連接對象args占用的內(nèi)存空間,供其他連接對象復(fù)用.
SocketListener類是通信服務(wù)器中的核心類,用來初始化連接池中的SocketAsyncEventArg 對象,開始監(jiān)聽用戶連接請求,從連接池中取出一個可用連接給用戶,對接收的數(shù)據(jù)進(jìn)行處理,向客戶端返回消息是否發(fā)送成功信息.該類的主要的方法如下:
(1) void Init():該方法初始化緩沖區(qū),創(chuàng)建一定數(shù)量的連接對象SocketAsyncEventArgs,設(shè)置對象屬性,將連接對象放入連接池.
(2)void StartListen (IPEndPoint ip):該方法在指定的端口開始接收連接請求,參數(shù)為端口的地址.該方法的主要代碼如下:
// 建立監(jiān)聽socket
listenSocket = new Socket(……);
//根據(jù)地址(IPV4或IPV6)分別綁定監(jiān)聽端口
this.listenSocket.Bind(localEndPoint); // 開始監(jiān)聽
listenSocket.Listen(100);
//開始接受連接
StartAccept(null);
(3)void ProcessReceive(SocketAsyncEventArgs e) :該方法用來處理接收的數(shù)據(jù),參數(shù)為接收數(shù)據(jù)的連接對象.該方法的處理流程如下:① 獲取接收數(shù)據(jù).利用SocketAsyncEventArgs對象的BytesTransferred屬性獲取接收的數(shù)據(jù),代碼為int byteReceived = e.BytesTransferred; ② 調(diào)用MessageHandler類的GetActualMessage方法對數(shù)據(jù)進(jìn)行數(shù)據(jù)拆包.③ 調(diào)用ProcessMessage方法對數(shù)據(jù)包分別進(jìn)行解析,獲取數(shù)據(jù)包的類型,根據(jù)數(shù)據(jù)包類型調(diào)用不同的方法對數(shù)據(jù)進(jìn)行解析,存入相應(yīng)數(shù)據(jù)庫.④ 向客戶端發(fā)送是否正確接收信息.
在通信服務(wù)器中,由于緩沖區(qū)的大小、網(wǎng)絡(luò)延遲或者操作系統(tǒng)處理方式的差異,特別是在客戶端請求時間比較短的情況下,服務(wù)器就會出現(xiàn)“粘包”現(xiàn)象,即發(fā)送方發(fā)送的若干包數(shù)據(jù)到接收方接收時粘成一包,從接收緩沖區(qū)看,后一包數(shù)據(jù)的頭緊接著前一包數(shù)據(jù)的尾.因此,為了保證數(shù)據(jù)準(zhǔn)確性,通信服務(wù)器需要對來自客戶端的數(shù)據(jù)進(jìn)行分包處理,然后再進(jìn)行解析.
MessageHandler類負(fù)責(zé)完成數(shù)據(jù)分包處理,該類GetMessage(string, List
① 利用正則表達(dá)式來判斷接收的字符是否與定義的協(xié)議匹配.
② 如果匹配,將第一個匹配的字符添加到字符串列表,然后縮短字符串長度,進(jìn)行遞歸調(diào)用,直到字符串為空.
③ 否則,將字符緩存,等待下一次請求.
界面管理類用來啟動或者關(guān)閉通信服務(wù)器,顯示已經(jīng)連接的遠(yuǎn)程終端信息,其運(yùn)行界面如圖2所示.
圖2 通信服務(wù)器界面Fig.2 Running interface of communication server
在界面管理類中實例化SocketListener類,調(diào)用該類的StartListen方法開始連接,主要代碼為:
listerner = new SocketListener(3000, 25);
listerner.StartListen(localAddress).
為了簡化數(shù)據(jù)庫操作,服務(wù)器將利用ADO.NET組件訪問SQL Server 2008數(shù)據(jù)庫的技術(shù)封裝為數(shù)據(jù)庫訪問類Database.數(shù)據(jù)訪問類Database實現(xiàn)的關(guān)鍵技術(shù)如下:① 利用ConfigurationManager類從應(yīng)用程序配置文件App.config讀取連接字符串,代碼為conn = ConfigurationManager.ConnectionStrings["RM"];② 利用連接字符串生成SqlConnection連接對象,代碼為SqlConnection con = new SqlConnection(conn);③ 封裝數(shù)據(jù)庫訪問方法,實現(xiàn)對數(shù)據(jù)庫的各種操作.
為了測試通信服務(wù)器的性能,在單機(jī)中做了系統(tǒng)性能測試.測試計算機(jī)的配置如下:CPU為Intel Core 2 Duo E7400(2.8GHZ),內(nèi)存2G,操作系統(tǒng)為 Windows XP Professional(SP3),客戶端采用控制臺程序來模擬遠(yuǎn)程終端,自動隨機(jī)地向服務(wù)器發(fā)送注冊消息、數(shù)據(jù)包以及心跳包.測試結(jié)果表明,客戶端數(shù)量達(dá)到6萬個時,系統(tǒng)還能夠100%的連接上,注冊和消息發(fā)送均能夠正確執(zhí)行,系統(tǒng)的CPU占用和內(nèi)存使用率都在合理的范圍之內(nèi),如圖3所示.
測試結(jié)果表明,基于SocketAsyncEventArgs技術(shù)的通信服務(wù)器與采用多線程和Socket編寫的傳統(tǒng)的通信服務(wù)器程序相比,服務(wù)器程序的處理效率有了明顯提高,時間和空間開銷減少,滿足了大規(guī)模的無線監(jiān)控系統(tǒng)多個終端同時并發(fā)處理的要求.
圖3 通信服務(wù)器測試效果圖Fig.3 Testing results of communication server
在對無線遠(yuǎn)程監(jiān)控系統(tǒng)應(yīng)用現(xiàn)狀調(diào)查的基礎(chǔ)上,本文提出了基于B/S框架的遠(yuǎn)程無線監(jiān)控系統(tǒng)的邏輯模型,利用C#語言和SQL Server 2008數(shù)據(jù)庫實現(xiàn)了一個高性能的遠(yuǎn)程監(jiān)控系統(tǒng)通用通信服務(wù)器程序.該服務(wù)器采用.NET類庫的SocketAsyncEventArgs對象建立連接池,提高了系統(tǒng)的I/O性能,支持大規(guī)模并發(fā)訪問,具有良好的擴(kuò)展性和通用性.