视频监控数据远程传输的设计与实现
2010-01-12高志国李巧鸽高新鹏
高志国,李巧鸽,高新鹏
(1.中原油田勘察设计研究院,河南濮阳 457001;2.中石化销售华北分公司河南输油管理处,郑州 450015)
0 引 言
中原油田天然气处理厂主要针对油田天然气进行深冷加工处理,天然气处理量1.2×106m3/d。由于该厂厂区范围大,生产车间多且分散,按照中石化安全生产的统一要求,在各关键生产点安装了视频监控系统,并将数据远传至生产调度室监控中心。监控系统包括本地和远程监控两部分。在远程监控中心和现场监控之间通过局域网络连接。远程监控中心可以任意对各个现场实行监控,既可以完成对现场视频图像数据的实时接收、解压缩、播放、存储以及控制该现场的摄像机切换,镜头、云台动作,又可以接收处理现场的报警信息。
1 设计原理简介
1.1 功能模块介绍
远程监控中心监控程序的设计主要涉及数据收发、分析处理及显示等模块。数据收发是控制台程序的重要部分,如果没有合理有效的收发模块设计方案,将影响到其他模块的正常运转。为了提高监控中心的运行效率,确保通信快速有效地进行,将数据收发模块做成了一个独立的基于Win32的控制台程序,采用了 Win32多线程编程技术和Socket网络编程技术。
1.2 Socket编程技术
在网络通信中最常用的协议是 TCP/IP协议簇。它已成为现代工厂生产网络的工业标准。Socket(套接字)最早是Unix系统中采用 TCP/IP协议簇而提供的网络通信接口,随着计算机操作系统的发展,Windows操作系统也采用了Socket,提供了 Window API供开发人员调用。Windows Socket(简称 WinSock)编程接口是 Windows环境下最广泛使用的网络编程接口。
2 数据收发的设计与实现
2.1 视频监控系统程序结构的设计
视频监控系统程序设计如图1所示。在服务器端分为2个功能模块:通信模块——数据收发程序;数据处理模块——监控中心控制台。远程监控中心服务器运行两个程序,数据收发程序和监控中心控制台。
图1 视频监控系统基本结构
2.2 数据采集器程序的设计
数据收发程序主要有三个功能:与远程服务器端通信;与控制台通信;操作数据库。与控制台数据通信主要是利用 Windows消息进行的,利用ADO技术实现数据采集器对数据库的操作;与远程服务器通信采用Socket编程技术。如何有效地与远程服务器端进行通信并将得到的数据有效地写入数据库,保证数据不丢失并传送到控制台是设计的核心和难点。
数据收发程序的线程设计如下:
a)主线程。初始化用于进行同步的事件变量,临界区变量,共享资源等,并建立一个侦听套接字,负责为新的服务器连接请求开启线程,建立传输套接字。当主线程收到结束程序的信号时将为各个线程发出终止事件,等待各个线程的终止,并释放资源。
b)远程控制线程。用来负责向远程服务器端发送控制命令。
c)远程监视进程。用来负责监视所有远程服务器端的运行状况以及网络状况,从而实现在控制中心实时显示服务器端的运行状态。
d)数据传输线程。该线程的数目与远程现场服务器端的数目相同,对应进行处理各个服务器发来的数据,将接收到的视频流信息和报警信息入库,并将接收到的数据发送给控制台进行数据分析处理。
e)数据传输维护线程。将数据传输线程做一个链表,实时维护此链表中各个线程的有效性(负责记录存在的线程,删除终止的线程并释放其资源,增加新建的线程)。该线程是为了解决数据传输线程复杂不易管理的问题,使得每一个线程都能够正常运行。成功解决了实际应用中曾经存在的启动多个线程的问题。具体执行过程如图2所示。
图2 数据收发模块流程
2.3 数据收发程序的实现
2.3.1 定义的数据结构和重要的全局变量
首先定义了一个用于描述每一个服务器端信息的数据结构 ClientInfo和一个服务器链表ClientList,分别如下所示:
数据结构ClientInfo不但记录了服务器的基本信息(如服务器端 IP),还记录了与该服务器端通信所对应的套接字标识sd和用于接收处理该服务器视频流的线程标识 ThreadID,目的是为了在程序运行过程中可以有效地控制系统的线程和套接字的开关情况。字段send_time和rec_time字段主要是用来察看远程服务器端运行状态用的。当rec_time或send_time与当前时间超过一定间隔时需要重新向服务器端发送状态请求数据包以检测其运行状态。ClientList是以ClientInfo为节点的链表结构。g_ci_list是系统定义的一个ClientList的全局指针变量,用来指向保存与控制中心正常连接的远程现场服务器列表。
另外定义的一个数据结构NewClientInfor和一个全局变量g_nci用来保存新连接请求的服务器端的基本信息。定义如下:typedef struct_ NewClientInfor{
2.3.2 线程的启动
创建一个新的线程是使用 WinAPI函数CreateThread。该函数的系统声明如下:
每一个线程定义其实现函数之后,通过在主线程中调用Creat Thread函数即开启了该线程。
2.3.3 网络通信的实现
对远程服务器数据的发送接收采用的是TCP套接字。由于多个线程和现场服务器端通信时用到同一个套接字,为了有效地对套接字进行使用,将其设定为非阻塞模式(Nonblocking),采用Select模型,利用 select函数,判断套接字上是否存在数据,或者能否向一个套接字写入数据。具体实现如下:
3 结束语
该方案利用多线程和套接字技术成功地解决了远程控制中心对多个现场监视的数据收发任务。该方案也适合类似于服务器和多服务器进行数据采集和控制的任何模型。线程间同步以及线程生存期内的维护是多线程编程应该注意的关键问题。由于多个线程同时需要对同一个套接字的使用,使用了非阻塞套接字模式和select模型,避免了在套接字处于非锁定模式中时,产生WSAEWOULDBLOCK错误。
[1] 刘富强.数字视频监控系统开发及应用[M].北京:机械工业出版社,2003.
[2] J EFFREY R.Windows高级编程指南[M].王书洪,刘光明译.北京:清华大学出版社,1999.
[3] ANTHONYJ.Windows网络编程技术[M].京京工作室译.北京:机械工业出版社,2000.
[4] 黄杰生.结合消息队列机制的多线程TCP通信开发平台[J].计算机应用研究,2004,(5):247-249.
[5] 李纳莹.利用MFC多线程技术开发基于UDP数据广播的局域网络会议程序[J].电脑编程技巧与维护,2004,(2):24.
[6] 蔡翠平,宋晓霞,苏学涛.多媒体计算机网络通信技术应用[M].北京:北京大学出版社,2007.
[7] 刘直芳,王运琼.数字图象处理与分析[M].北京:清华大学出版社,2006.