基于GPRS的車輛監(jiān)控系統(tǒng)技術(shù)研究
CP和UDP協(xié)議同在傳輸層,由于本系統(tǒng)每次傳輸?shù)臄?shù)據(jù)量小而且突發(fā)性強,所以采用UDP協(xié)議傳輸數(shù)據(jù)。UDP協(xié)議的主要作用是將網(wǎng)絡(luò)數(shù)據(jù)流壓縮成數(shù)據(jù)報的形式。一個典型的數(shù)據(jù)報就是一個二進制數(shù)據(jù)的傳輸單位。UDP協(xié)議為不可靠的傳輸協(xié)議,不提供數(shù)據(jù)傳送的保障機制。如果在從發(fā)送方到接收方的傳遞過程中出現(xiàn)數(shù)據(jù)報的丟失,協(xié)議本身并不能做出任何檢測或提示。因此,必須在應(yīng)用層的協(xié)議中添加保障信息傳輸可靠性的確認機制。監(jiān)控中心向終端下傳數(shù)據(jù)時,要求終端返回接收正確或錯誤的確認信息,監(jiān)控中心收到正確的確認信息后數(shù)據(jù)下傳進程才完畢。否則,監(jiān)控中心將在規(guī)定的時間內(nèi)重發(fā),直到收到正確的確認信息或發(fā)送次數(shù)標志溢出才終止。
GPRS網(wǎng)絡(luò)UDP端口資源十分緊缺,變化很快;UDP由于自身特點,以及GPRS網(wǎng)絡(luò)UDP端口資源的有限性,在一段時間沒有數(shù)據(jù)流量后,端口容易改變,產(chǎn)生的影響就是從服務(wù)器中心端向GPRS終端發(fā)送數(shù)據(jù),GPRS終端接收不到。原因是移動網(wǎng)關(guān)從中做了中轉(zhuǎn),需要隔一定時間給主機發(fā)UDP包來維持該IP和端口號,這樣主機就能主動給GPRS發(fā)UDP包,筆者在測試中發(fā)現(xiàn),這個間隔時間很短,約1 min發(fā)一次UDP包才能夠維持,再長時間移動網(wǎng)關(guān)那邊就要丟失這個端口了,逾期主機想主動發(fā)數(shù)據(jù)給終端,將無法送達。只有GPRS終端設(shè)備重新發(fā)一個UDP包過去,移動再分配一個中轉(zhuǎn)IP和端口,才能夠進行雙向通信。為保證端口有效性和數(shù)據(jù)實時性,終端設(shè)備每5 s發(fā)送一條包含定位和狀態(tài)的數(shù)據(jù)給服務(wù)器。
2.2 基于C#發(fā)送、接收UDP數(shù)據(jù)包使用的主要方法
(1)UDP數(shù)據(jù)類。用Visual C#實現(xiàn)UDP協(xié)議,最為常用,也是最為關(guān)鍵的類就是UdpClient,UdpClient位于命名空間System.Net.Sock ets中,Visual C#發(fā)送、接收UDP數(shù)據(jù)包都是通過UdpClient類的。UdpClient類主要有以下幾個方法,見表1。本文引用地址:http://www.ex-cimer.com/article/197032.htm
(2)接受終端UDP數(shù)據(jù)。接收UDP數(shù)據(jù)包使用的是UdpClient中的“Receive”方法。此方法的調(diào)用語法如下:public byte[]Receive(ref IPEndPoint remoteEP);參數(shù)remoteEP是一個IPEndPoint類的實例,它表示網(wǎng)絡(luò)中發(fā)送此數(shù)據(jù)包的節(jié)點。下面就是通過偵聽本地端口號“8 080”來獲取信息代碼:
UdpClient server=new UdpClient(8080);
IPEndPoint receivePoint=new IPEndPoint(IPAddress.Any,0);
byte[]recData=server.Receive(ref receivePoint);
recData就是接受到的UDP報文,其中UDP包頭結(jié)構(gòu)如下:源端口16位,目的端口16位,長度16位,校驗和16位;上文中闡述了GPRS的UDP端口非常緊缺,隨時會變化,在每次接受到UDP報文后,必須記錄源端口、IP地址。receivePoint參數(shù)是引用類型,receive到新的UDP后,receivePoint對象的address和port屬性值就是發(fā)送源的IP地址和端口。這個IP和端口未必是真的終端的IP和端口。因為終端上的應(yīng)用程序綁定本地一個端口(比如是9002),通過這個端口發(fā)送請求給路由器,路由器由此記錄下終端的內(nèi)網(wǎng)IP和端口(9002),然后路由器分配自己的一個空閑端口(比如是7000),通過這個端口(7000)發(fā)送請求給監(jiān)控中心。而對于監(jiān)控中心,它沒有任何關(guān)于終端的信息,它要做的只是回信息到路由器的外網(wǎng)IP的7000這個端口。路由器收到發(fā)送到其7000端口的數(shù)據(jù)后會再轉(zhuǎn)發(fā)給終端。
(3)發(fā)送UDP數(shù)據(jù)報。發(fā)送UDP數(shù)據(jù)報使用“Send”方法。“Send”方法的調(diào)用語法如下:public int Send(byte[]dgram,int bytes,IPEndPoint endPoint);參數(shù)說明:dgram要發(fā)送的UDP數(shù)據(jù)文報(以字節(jié)數(shù)組表示)。bytes數(shù)據(jù)文報中的字節(jié)數(shù)。endPoint一個IPEndPoint,它表示要將數(shù)據(jù)文報發(fā)送到的主機和端口。返回值是已發(fā)送的字節(jié)數(shù)。下面使用UDPClient發(fā)送UDP數(shù)據(jù)包的具體的調(diào)用例子:
該代碼實現(xiàn)了對某終端發(fā)送UDP報文后的回復。如果需要主動向終端發(fā)送報文則需要從數(shù)據(jù)庫中提取該終端最近一次的IP和端口號,調(diào)用該方法發(fā)送內(nèi)容。
2.3 數(shù)據(jù)封裝和轉(zhuǎn)存
監(jiān)控中心與客戶端的數(shù)據(jù)通信包含2種:一種是上行數(shù)據(jù),一種是下行數(shù)據(jù)。上行數(shù)據(jù)包含終端匯報車輛的狀態(tài)信息,車輛實時信息,車輛語音信息,視頻信息等。下行信息包含對終端的回應(yīng),車輛的實時控制等信息。數(shù)據(jù)種類大約一百多種,可分為20多種格式。針對每種格式定義一個結(jié)構(gòu)進行數(shù)據(jù)接受和轉(zhuǎn)存到數(shù)據(jù)庫,進行數(shù)據(jù)顯示和分析。終端返回數(shù)據(jù)一般是結(jié)構(gòu)類型,為保證數(shù)據(jù)轉(zhuǎn)換準確和便捷,C#也使用同樣的結(jié)構(gòu)對數(shù)據(jù)進行接受。上文中UDP報文接受到的正文是byte類型,該byte內(nèi)容有報文頭和報文類型、校驗部分和正文構(gòu)成。根據(jù)報文類型找到對應(yīng)的C#結(jié)構(gòu)體structType。利用Marshal.SizeOf(structType);獲取結(jié)構(gòu)體大小,并進行分配空間:IntPtrstructPtr=Marsh al.AllocHGlobal(size);然后將byte數(shù)組拷到分配好的內(nèi)存空間:Marshal.Copy(recData,0,structPtr,size);將內(nèi)存空間轉(zhuǎn)換為目標結(jié)構(gòu)體objectobj=Marshal.PtrToStructure(structPtr. struct Type)。為提高系統(tǒng)的實時響應(yīng)速度,這些數(shù)據(jù)分為2種處理方式,如非緊急數(shù)據(jù)直接保存到數(shù)據(jù)庫,而如果是緊急數(shù)據(jù),比如車輛報警數(shù)據(jù),車輛控制數(shù)據(jù)則直接通過Socket連接發(fā)送到Web服務(wù)器,由Web服務(wù)器推送到瀏覽器監(jiān)控端。
3 結(jié)語
本文主要分析了監(jiān)控系統(tǒng)的GPRS通信技術(shù),詳細介紹了基于GPRS的UDP數(shù)據(jù)通信流程和方法,實現(xiàn)了C#環(huán)境下接受,發(fā)送UDP數(shù)據(jù)報文,協(xié)議的定制,數(shù)據(jù)轉(zhuǎn)存等關(guān)鍵技術(shù)。本文解決的問題是監(jiān)控系統(tǒng)的核心內(nèi)容,但并不是全部,一個完整的系統(tǒng)還應(yīng)包括終端硬件設(shè)計以及后臺監(jiān)控軟件、GIS地圖顯示等許多方面。今后,應(yīng)通過進一步的研究。解決系統(tǒng)其他相關(guān)技術(shù)。
評論