高志國,李巧鴿,高新鵬
(1.中原油田勘察設(shè)計(jì)研究院,河南濮陽 457001;2.中石化銷售華北分公司河南輸油管理處,鄭州 450015)
中原油田天然氣處理廠主要針對(duì)油田天然氣進(jìn)行深冷加工處理,天然氣處理量1.2×106m3/d。由于該廠廠區(qū)范圍大,生產(chǎn)車間多且分散,按照中石化安全生產(chǎn)的統(tǒng)一要求,在各關(guān)鍵生產(chǎn)點(diǎn)安裝了視頻監(jiān)控系統(tǒng),并將數(shù)據(jù)遠(yuǎn)傳至生產(chǎn)調(diào)度室監(jiān)控中心。監(jiān)控系統(tǒng)包括本地和遠(yuǎn)程監(jiān)控兩部分。在遠(yuǎn)程監(jiān)控中心和現(xiàn)場監(jiān)控之間通過局域網(wǎng)絡(luò)連接。遠(yuǎn)程監(jiān)控中心可以任意對(duì)各個(gè)現(xiàn)場實(shí)行監(jiān)控,既可以完成對(duì)現(xiàn)場視頻圖像數(shù)據(jù)的實(shí)時(shí)接收、解壓縮、播放、存儲(chǔ)以及控制該現(xiàn)場的攝像機(jī)切換,鏡頭、云臺(tái)動(dòng)作,又可以接收處理現(xiàn)場的報(bào)警信息。
遠(yuǎn)程監(jiān)控中心監(jiān)控程序的設(shè)計(jì)主要涉及數(shù)據(jù)收發(fā)、分析處理及顯示等模塊。數(shù)據(jù)收發(fā)是控制臺(tái)程序的重要部分,如果沒有合理有效的收發(fā)模塊設(shè)計(jì)方案,將影響到其他模塊的正常運(yùn)轉(zhuǎn)。為了提高監(jiān)控中心的運(yùn)行效率,確保通信快速有效地進(jìn)行,將數(shù)據(jù)收發(fā)模塊做成了一個(gè)獨(dú)立的基于Win32的控制臺(tái)程序,采用了 Win32多線程編程技術(shù)和Socket網(wǎng)絡(luò)編程技術(shù)。
在網(wǎng)絡(luò)通信中最常用的協(xié)議是 TCP/IP協(xié)議簇。它已成為現(xiàn)代工廠生產(chǎn)網(wǎng)絡(luò)的工業(yè)標(biāo)準(zhǔn)。Socket(套接字)最早是Unix系統(tǒng)中采用 TCP/IP協(xié)議簇而提供的網(wǎng)絡(luò)通信接口,隨著計(jì)算機(jī)操作系統(tǒng)的發(fā)展,Windows操作系統(tǒng)也采用了Socket,提供了 Window API供開發(fā)人員調(diào)用。Windows Socket(簡稱 WinSock)編程接口是 Windows環(huán)境下最廣泛使用的網(wǎng)絡(luò)編程接口。
視頻監(jiān)控系統(tǒng)程序設(shè)計(jì)如圖1所示。在服務(wù)器端分為2個(gè)功能模塊:通信模塊——數(shù)據(jù)收發(fā)程序;數(shù)據(jù)處理模塊——監(jiān)控中心控制臺(tái)。遠(yuǎn)程監(jiān)控中心服務(wù)器運(yùn)行兩個(gè)程序,數(shù)據(jù)收發(fā)程序和監(jiān)控中心控制臺(tái)。
圖1 視頻監(jiān)控系統(tǒng)基本結(jié)構(gòu)
數(shù)據(jù)收發(fā)程序主要有三個(gè)功能:與遠(yuǎn)程服務(wù)器端通信;與控制臺(tái)通信;操作數(shù)據(jù)庫。與控制臺(tái)數(shù)據(jù)通信主要是利用 Windows消息進(jìn)行的,利用ADO技術(shù)實(shí)現(xiàn)數(shù)據(jù)采集器對(duì)數(shù)據(jù)庫的操作;與遠(yuǎn)程服務(wù)器通信采用Socket編程技術(shù)。如何有效地與遠(yuǎn)程服務(wù)器端進(jìn)行通信并將得到的數(shù)據(jù)有效地寫入數(shù)據(jù)庫,保證數(shù)據(jù)不丟失并傳送到控制臺(tái)是設(shè)計(jì)的核心和難點(diǎn)。
數(shù)據(jù)收發(fā)程序的線程設(shè)計(jì)如下:
a)主線程。初始化用于進(jìn)行同步的事件變量,臨界區(qū)變量,共享資源等,并建立一個(gè)偵聽套接字,負(fù)責(zé)為新的服務(wù)器連接請求開啟線程,建立傳輸套接字。當(dāng)主線程收到結(jié)束程序的信號(hào)時(shí)將為各個(gè)線程發(fā)出終止事件,等待各個(gè)線程的終止,并釋放資源。
b)遠(yuǎn)程控制線程。用來負(fù)責(zé)向遠(yuǎn)程服務(wù)器端發(fā)送控制命令。
c)遠(yuǎn)程監(jiān)視進(jìn)程。用來負(fù)責(zé)監(jiān)視所有遠(yuǎn)程服務(wù)器端的運(yùn)行狀況以及網(wǎng)絡(luò)狀況,從而實(shí)現(xiàn)在控制中心實(shí)時(shí)顯示服務(wù)器端的運(yùn)行狀態(tài)。
d)數(shù)據(jù)傳輸線程。該線程的數(shù)目與遠(yuǎn)程現(xiàn)場服務(wù)器端的數(shù)目相同,對(duì)應(yīng)進(jìn)行處理各個(gè)服務(wù)器發(fā)來的數(shù)據(jù),將接收到的視頻流信息和報(bào)警信息入庫,并將接收到的數(shù)據(jù)發(fā)送給控制臺(tái)進(jìn)行數(shù)據(jù)分析處理。
e)數(shù)據(jù)傳輸維護(hù)線程。將數(shù)據(jù)傳輸線程做一個(gè)鏈表,實(shí)時(shí)維護(hù)此鏈表中各個(gè)線程的有效性(負(fù)責(zé)記錄存在的線程,刪除終止的線程并釋放其資源,增加新建的線程)。該線程是為了解決數(shù)據(jù)傳輸線程復(fù)雜不易管理的問題,使得每一個(gè)線程都能夠正常運(yùn)行。成功解決了實(shí)際應(yīng)用中曾經(jīng)存在的啟動(dòng)多個(gè)線程的問題。具體執(zhí)行過程如圖2所示。
圖2 數(shù)據(jù)收發(fā)模塊流程
2.3.1 定義的數(shù)據(jù)結(jié)構(gòu)和重要的全局變量
首先定義了一個(gè)用于描述每一個(gè)服務(wù)器端信息的數(shù)據(jù)結(jié)構(gòu) ClientInfo和一個(gè)服務(wù)器鏈表ClientList,分別如下所示:
數(shù)據(jù)結(jié)構(gòu)ClientInfo不但記錄了服務(wù)器的基本信息(如服務(wù)器端 IP),還記錄了與該服務(wù)器端通信所對(duì)應(yīng)的套接字標(biāo)識(shí)sd和用于接收處理該服務(wù)器視頻流的線程標(biāo)識(shí) ThreadID,目的是為了在程序運(yùn)行過程中可以有效地控制系統(tǒng)的線程和套接字的開關(guān)情況。字段send_time和rec_time字段主要是用來察看遠(yuǎn)程服務(wù)器端運(yùn)行狀態(tài)用的。當(dāng)rec_time或send_time與當(dāng)前時(shí)間超過一定間隔時(shí)需要重新向服務(wù)器端發(fā)送狀態(tài)請求數(shù)據(jù)包以檢測其運(yùn)行狀態(tài)。ClientList是以ClientInfo為節(jié)點(diǎn)的鏈表結(jié)構(gòu)。g_ci_list是系統(tǒng)定義的一個(gè)ClientList的全局指針變量,用來指向保存與控制中心正常連接的遠(yuǎn)程現(xiàn)場服務(wù)器列表。
另外定義的一個(gè)數(shù)據(jù)結(jié)構(gòu)NewClientInfor和一個(gè)全局變量g_nci用來保存新連接請求的服務(wù)器端的基本信息。定義如下:typedef struct_ NewClientInfor{
2.3.2 線程的啟動(dòng)
創(chuàng)建一個(gè)新的線程是使用 WinAPI函數(shù)CreateThread。該函數(shù)的系統(tǒng)聲明如下:
每一個(gè)線程定義其實(shí)現(xiàn)函數(shù)之后,通過在主線程中調(diào)用Creat Thread函數(shù)即開啟了該線程。
2.3.3 網(wǎng)絡(luò)通信的實(shí)現(xiàn)
對(duì)遠(yuǎn)程服務(wù)器數(shù)據(jù)的發(fā)送接收采用的是TCP套接字。由于多個(gè)線程和現(xiàn)場服務(wù)器端通信時(shí)用到同一個(gè)套接字,為了有效地對(duì)套接字進(jìn)行使用,將其設(shè)定為非阻塞模式(Nonblocking),采用Select模型,利用 select函數(shù),判斷套接字上是否存在數(shù)據(jù),或者能否向一個(gè)套接字寫入數(shù)據(jù)。具體實(shí)現(xiàn)如下:
該方案利用多線程和套接字技術(shù)成功地解決了遠(yuǎn)程控制中心對(duì)多個(gè)現(xiàn)場監(jiān)視的數(shù)據(jù)收發(fā)任務(wù)。該方案也適合類似于服務(wù)器和多服務(wù)器進(jìn)行數(shù)據(jù)采集和控制的任何模型。線程間同步以及線程生存期內(nèi)的維護(hù)是多線程編程應(yīng)該注意的關(guān)鍵問題。由于多個(gè)線程同時(shí)需要對(duì)同一個(gè)套接字的使用,使用了非阻塞套接字模式和select模型,避免了在套接字處于非鎖定模式中時(shí),產(chǎn)生WSAEWOULDBLOCK錯(cuò)誤。
[1] 劉富強(qiáng).數(shù)字視頻監(jiān)控系統(tǒng)開發(fā)及應(yīng)用[M].北京:機(jī)械工業(yè)出版社,2003.
[2] J EFFREY R.Windows高級(jí)編程指南[M].王書洪,劉光明譯.北京:清華大學(xué)出版社,1999.
[3] ANTHONYJ.Windows網(wǎng)絡(luò)編程技術(shù)[M].京京工作室譯.北京:機(jī)械工業(yè)出版社,2000.
[4] 黃杰生.結(jié)合消息隊(duì)列機(jī)制的多線程TCP通信開發(fā)平臺(tái)[J].計(jì)算機(jī)應(yīng)用研究,2004,(5):247-249.
[5] 李納瑩.利用MFC多線程技術(shù)開發(fā)基于UDP數(shù)據(jù)廣播的局域網(wǎng)絡(luò)會(huì)議程序[J].電腦編程技巧與維護(hù),2004,(2):24.
[6] 蔡翠平,宋曉霞,蘇學(xué)濤.多媒體計(jì)算機(jī)網(wǎng)絡(luò)通信技術(shù)應(yīng)用[M].北京:北京大學(xué)出版社,2007.
[7] 劉直芳,王運(yùn)瓊.數(shù)字圖象處理與分析[M].北京:清華大學(xué)出版社,2006.