APP下载

基于SocketAsyncEventArgs的远程监控系统通信服务器设计与实现

2015-08-09曾宪权

关键词:客户端远程终端

曾宪权,肜 瑶

(1.许昌学院 信息工程学院,河南 许昌 461000;2.黄河科技学院 信息工程学院,河南 郑州 450063)

0 引言

随着计算机和无线通信技术的发展,采用Internet与无线通信技术相结合构建的新型无线远程监控系统已经广泛地应用到工业、交通、公安、电力和水利等行业,成为现代安防系统的一个重要分支[1].在无线远程监控系统中,通信服务器是系统的核心部件,负责接收远程监控终端上传的数据,并对接收的数据进行解析、处理后存入数据库,或者转发应用系统发送的终端控制指令以便调整终端的工作状态,其设计的优劣直接影响整个系统的性能.

对于如何构建通信服务器,周钦强[2]等采用动态线程池技术来解决线程创建中的时间延迟,并根据客户端数量的变化动态调整线程池中线程的数量.树爱兵等[3]利用IOCP设计和实现了通信服务器,用于交通控制系统中的路口信号机、监控终端及其控制软件的数据通信及处理.原仓周等[4]针对远程车辆监控系统远程终端数量多,通信频繁的特点,综合利用Socket和多线程技术实现了大规模车辆监控系统的通信服务器,实现了远程终端与服务器之间的交互.这些通信服务器基本上都采用了Socket通信和多线程技术来实现.随着客户数量的增加,系统中的线程和Socket的数量会显著增加,从而导致系统资源匮乏,系统性能下降.另一方面,随着线程数量的增加,线程之间的同步和管理也会越来越复杂,从而影响了系统的性能.为了解决这些问题,利用.NET2.0及其以上类库中的SocketAsyncEventArgs类设计和实现了一个高性能的通信服务器,采用异步调用.NET Socket类中的方法和连接池技术来提高服务器的性能,支持大规模客户端的并发访问,实现无阻塞的输入和输出.

1 无线远程监控系统的逻辑模型

一个典型的无线远程监控系统通常由数据采集层、数据传输层、数据中心和应用系统组成,其逻辑模型如图1所示.

图1 无线远程监控系统逻辑模型Fig.1 Logical model of wireless remote monitoring system

数据采集层利用现场的终端设备采集监控现场信息,通过无线通信模块将信息上传到数据中心的通信服务器,也可以接收来自监控系统的控制命令并采取相应的动作.

数据传输层是数据采集终端与数据中心的通信服务器以及应用系统进行数据通信的通道,利用公共无线通信网络(如GPRS/CDMA等)和Internet网络实现远程终端设备与数据中心的数据交互[5].

数据中心是远程无线监控系统的数据共享中心,由通信服务器、数据库服务器和应用服务器组成.通信服务器是Internet网络上具有固定IP的计算机,它负责接收数据采集终端上传的数据,按照约定的协议解析后存入数据库.通信服务器也可以将监控系统发送的控制命令转发到远程终端以控制远程终端的行为.应用服务器根据客户端请求从数据库服务器读取数据库,进行相应的处理后,按照应用系统的要求以表格、图形或文字的形式将结果显示在监控系统的客户计算机上,从而实现数据采集终端和监控系统的信息交互.

应用系统是远程无线监控系统的客户端,通常采用B/S框架结构,利用各种浏览器访问应用服务器中的程序,获取远程终端设备传送的数据[6],及时了解监控现场的信息或者向远程终端设备发送控制命令.

2 无线远程监控系统通信服务器设计

在无线远程监控系统中,通信服务器是各种数据的中转站,是一个支持多连接长时间的实时通讯服务器[7],其主要功能如下:(1)建立通讯端口,监听远程终端发送的连接请求;(2)建立连接通道,从Internet网络上接收远程监控终端发送的数据,按照约定的协议对接收的数据进行解析,将解析后的原始数据存入数据库.(3) 转发监控系统发送的控制命令到远程终端设备,以控制远程终端的数据读取或参数设置,实现远程终端与监控系统的交互.

2.1 通信服务器的结构

根据通信服务器的功能和网络通信的特点,通信服务器从功能上可分为用户界面、服务器管理、数据解析和处理、DTU(Data Transfer Unit)管理和数据访问等几个功能模块.

(1)用户界面负责初始化DTU队列,启动服务器,显示在线DTU的信息.

(2)服务器管理模块是通信服务器程序的核心,用于创建连接、接收和发送消息以及关闭连接,其性能是整个通信服务器程序的瓶颈.在设计时,采用了以下技术来提高服务器性能.①利用缓冲池来管理消息缓冲区,实现缓冲区的重用,减少内存碎片;②建立2个SocketAsyncEventArgs对象,一个用于接收消息,一个用于发送消息,实现双工通信,提高通信效率;③利用接池技术,实现了SocketAsyncEventArgs对象的复用,减少了时空开销;④定时扫描连接对象,清除超时的连接对象,释放其占用的资源.

(3)数据解析和处理模块完成消息的接收和处理.服务器在接收到消息后,首先对接收的消息进行准确性验证,以防止出现半个数据包造成的丢包现象,然后按照约定的协议对消息进行解析,按照消息的类型存入相应的数据表.

(4)数据访问模块利用数据库连接工具将验证后的数据写入数据库.该模块首先利用ADO.NET建立连接池,然后根据需要对数据库进行读写操作.

(5)DTU管理模块记录在线的远程终端的信息,以便于进行设备识别和消息发送.

2.2 通信规约的设计

根据无线远程监控系统的通信特点,设计了如表1所示的通信协议,以便有效处理异步通信中的TCP/IP消息无边界问题,保证数据的可靠性.

表1 系统数据报文格式Tab.1 Format of system message

说明:1. 消息头和消息尾:用来标识消息的开始和结束位置.为了避免与消息内容相混淆,消息头和消息尾分别采用字符串“<<<”和“>>>”;2. 类型域:用来区分消息的类型,用一个字符表示.消息可分为设备注册0x31、数据0x32、命令0x33和心跳包0x34等几种类型;3. DTU编码:用来标识远程终端设备,用18个字符表示,每个DTU有唯一的编码;4. 内容域:发送的消息的内容,长度不限,其具体内容由消息类型决定.如果是注册包,该区域内容为空.

3 高性能通信服务器的实现

为了减少线程阻塞,提高通信服务的I/O性能,无线远程监控系统的通信服务器采用了异步编程模型AMP[8](Asynchronous Programming Model),利用.NET 提供的SocketAsyncEventArgs 类[9]的方法来异步接收客户端数据,使用缓冲池和连接池来提高系统的效率,支持大量的客户并发访问.下面对系统实现的主要类做详细说明.

3.1 SocketAsyncEventArgsPool类

SocketAsyncEventArgsPool类是连接池类,主要为服务器提供可用的用户连接,并且维持这个连接直到用户断开,把空闲的连接对象放回连接池供下一个用户连接重用.该类的主要方法如下:

(1) SocketAsyncEventArgsPool(int capacity):类的构造函数,参数为连接池中连接对象的数量.

(2)void Push (SocketAsyncEventArgs item):将空闲的连接对象放回连接池,实现连接对象的复用.

(3)SocketAsyncEventArgs Pop():该方法从连接池中获取可用连接,开始进行数据接收.

3.2 BufferManager类

BufferManager类用来管理连接缓冲区,为每一个连接维持一个接收数据的区域,以减少内存碎片,提高内存利用率.该类的主要方法如下:

(1)void InitBuffer() :该方法用于设置缓冲池的容量.

(2)bool SetBuffer(SocketAsyncEventArgs args):该方法为连接对象args分配接收缓冲区,用来缓存客户端发送来的消息.

(3) void FreeBuffer(SocketAsyncEventArgs args):该方法释放连接对象args占用的内存空间,供其他连接对象复用.

3.3 SocketListener类

SocketListener类是通信服务器中的核心类,用来初始化连接池中的SocketAsyncEventArg 对象,开始监听用户连接请求,从连接池中取出一个可用连接给用户,对接收的数据进行处理,向客户端返回消息是否发送成功信息.该类的主要的方法如下:

(1) void Init():该方法初始化缓冲区,创建一定数量的连接对象SocketAsyncEventArgs,设置对象属性,将连接对象放入连接池.

(2)void StartListen (IPEndPoint ip):该方法在指定的端口开始接收连接请求,参数为端口的地址.该方法的主要代码如下:

// 建立监听socket

listenSocket = new Socket(……);

//根据地址(IPV4或IPV6)分别绑定监听端口

this.listenSocket.Bind(localEndPoint); // 开始监听

listenSocket.Listen(100);

//开始接受连接

StartAccept(null);

(3)void ProcessReceive(SocketAsyncEventArgs e) :该方法用来处理接收的数据,参数为接收数据的连接对象.该方法的处理流程如下:① 获取接收数据.利用SocketAsyncEventArgs对象的BytesTransferred属性获取接收的数据,代码为int byteReceived = e.BytesTransferred; ② 调用MessageHandler类的GetActualMessage方法对数据进行数据拆包.③ 调用ProcessMessage方法对数据包分别进行解析,获取数据包的类型,根据数据包类型调用不同的方法对数据进行解析,存入相应数据库.④ 向客户端发送是否正确接收信息.

3.4 MessageHandler类

在通信服务器中,由于缓冲区的大小、网络延迟或者操作系统处理方式的差异,特别是在客户端请求时间比较短的情况下,服务器就会出现“粘包”现象,即发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾.因此,为了保证数据准确性,通信服务器需要对来自客户端的数据进行分包处理,然后再进行解析.

MessageHandler类负责完成数据分包处理,该类GetMessage(string, List)方法对接收的数据进行分包处理.处理流程如下:

① 利用正则表达式来判断接收的字符是否与定义的协议匹配.

② 如果匹配,将第一个匹配的字符添加到字符串列表,然后缩短字符串长度,进行递归调用,直到字符串为空.

③ 否则,将字符缓存,等待下一次请求.

3.5 界面管理类

界面管理类用来启动或者关闭通信服务器,显示已经连接的远程终端信息,其运行界面如图2所示.

图2 通信服务器界面Fig.2 Running interface of communication server

在界面管理类中实例化SocketListener类,调用该类的StartListen方法开始连接,主要代码为:

listerner = new SocketListener(3000, 25);

listerner.StartListen(localAddress).

3.6 数据库访问类

为了简化数据库操作,服务器将利用ADO.NET组件访问SQL Server 2008数据库的技术封装为数据库访问类Database.数据访问类Database实现的关键技术如下:① 利用ConfigurationManager类从应用程序配置文件App.config读取连接字符串,代码为conn = ConfigurationManager.ConnectionStrings["RM"];② 利用连接字符串生成SqlConnection连接对象,代码为SqlConnection con = new SqlConnection(conn);③ 封装数据库访问方法,实现对数据库的各种操作.

4 性能测试和分析

为了测试通信服务器的性能,在单机中做了系统性能测试.测试计算机的配置如下:CPU为Intel Core 2 Duo E7400(2.8GHZ),内存2G,操作系统为 Windows XP Professional(SP3),客户端采用控制台程序来模拟远程终端,自动随机地向服务器发送注册消息、数据包以及心跳包.测试结果表明,客户端数量达到6万个时,系统还能够100%的连接上,注册和消息发送均能够正确执行,系统的CPU占用和内存使用率都在合理的范围之内,如图3所示.

测试结果表明,基于SocketAsyncEventArgs技术的通信服务器与采用多线程和Socket编写的传统的通信服务器程序相比,服务器程序的处理效率有了明显提高,时间和空间开销减少,满足了大规模的无线监控系统多个终端同时并发处理的要求.

图3 通信服务器测试效果图Fig.3 Testing results of communication server

5 结束语

在对无线远程监控系统应用现状调查的基础上,本文提出了基于B/S框架的远程无线监控系统的逻辑模型,利用C#语言和SQL Server 2008数据库实现了一个高性能的远程监控系统通用通信服务器程序.该服务器采用.NET类库的SocketAsyncEventArgs对象建立连接池,提高了系统的I/O性能,支持大规模并发访问,具有良好的扩展性和通用性.

猜你喜欢

客户端远程终端
让人胆寒的“远程杀手”:弹道导弹
远程工作狂综合征
X美术馆首届三年展:“终端〉_How Do We Begin?”
通信控制服务器(CCS)维护终端的设计与实现
如何看待传统媒体新闻客户端的“断舍离”?
远程诈骗
县级台在突发事件报道中如何应用手机客户端
孵化垂直频道:新闻客户端新策略
GSM-R手持终端呼叫FAS失败案例分析
大枢纽 云平台 客户端——中央人民广播电台的探索之路