用C编写一个XML格式的请求报文

2016-07-26 模板 阅读:

用C编写一个XML格式的请求报文(一)
HTTP请求报文格式

HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的。HTTP有两类报文:请求报文和响应报文。

请求报文

一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成,下图给出了请求报文的一般格式。

(1)请求行

请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。例如,GET /index.html HTTP/1.1。

HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。这里介绍最常用的GET方法和POST方法。

GET:当客户端要从服务器中读取文档时,使用GET方法。GET方法要求服务器将URL定位的资源放在响应报文的数据部分,回送给客户端。使用GET方法时,请求参数和对应的值附加在URL后面,利用一个问号(“?”)代表URL的结尾与请求参数的开始,传递参数长度受限制。例如,

/index.jsp?id=100&op=bind。

POST:当客户端给服务器提供信息较多时可以使用POST方法。POST方法将请求参数封装在HTTP请求数据中,以名称/值的形式出现,可以传输大量数据。

(2)请求头部

请求头部由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:

User-Agent:产生请求的浏览器类型。

Accept:客户端可识别的内容类型列表。

Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。

(3)空行

最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。

(4)请求数据

请求数据不在GET方法中使用,而是在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求数据相关的最常使用的请求头是Content-Type和Content-Length。

GET /qingdao.html HTTP/1.1 Accept:text/<>html, */* Accept-Language:zh-cn Accept-Encoding:gzip,deflate User-Agent:Mozilla/4.0(compatible;MSIE 5.01;Windows NT 5.0;DigExt) Host:

3 Content-Type: application/x-

4 Content-Length: length

5

6 UserID=string&PWD=string&OrderConfirmation=string

接收 ?

1

2 HTTP/1.1 200 OK 3 Content-Type: text/xml; charset=utf-8 4 Content-Length: length 5 6 <?xmlversion="1.0"encoding="utf-8"?> 7 <objPlaceOrderResponsexmlns="https://api.efxnow.com/webservices2.3"8 > 9 <Success>boolean</Success> 1<ErrorDescription>string</ErrorDescription> 0 <ErrorNumber>int</ErrorNumber> 1<CustomerOrderReference>long</CustomerOrderReference> 1 <OrderConfirmation>string</OrderConfirmation> 1<CustomerDealRef>string</CustomerDealRef> 2 </objPlaceOrderResponse> 1

3

用C编写一个XML格式的请求报文(二)
xml报文格式

xml报文协议

1. 清除缓存命令

1.1 发送

<?xml version="1.0" encoding="UTF-8"?>

<request id=”clear” version=”0.1”>

<!—要清除缓存域名-->

<domain></domain>

</request>

1.2 回应

<?xml version="1.0" encoding="UTF-8"?>

<response id =”ping” version=”0.1” flag=”1”><!—1成功,0失败>

</response>

2. ping命令

1.1 发送报文

<?xml version="1.0" encoding="UTF-8"?>

<request id=”ping” version=”0.1”>

<!—要ping的域名或者ip-->

<name></name>

</request>

1.2 返回报文

注:ping只返回四包数据

<?xml version="1.0" encoding="UTF-8"?>

<response id =”ping” version=”0.1” flag=”1”><!--1成功,0失败-->

<source>源报文<source> <ip>121.14.0.18</ip> <send>4</send>发送次数 <received>4</received>接收次数 <minimum>45</minimum>最短响应时间 <maximum>151</maximum>最长响应时间 <average>88</average>平均响应时间 </response>

3. traceroute命令

2.1 发送报文

<?xml version="1.0" encoding="UTF-8"?>

<request id =”traceroute” version=”0.1”>

<name>gtone.idcsea.com</name>

</request>

2.2 返回报文1

<?xml version="1.0" encoding="UTF-8"?>

<response id =”traceroutstart” version=”0.1” flag=”1”><!--1成功,0失败-->

<endIp>114.80.212.230 </endIp>路由终点

<max>30</max>节点上限

</response>

2.3 返回报文2

<?xml version="1.0" encoding="UTF-8"?>

<response id =”tracerout” version=”0.1” flag=”1”><!--1成功,0失败--> <no>1</no>节点序号

<ip>114.80.212.129</ip> <time1>24.258 ms</time1>响应时间1 <time2>25.332ms</time2>响应时间2 <time3>23.32ms</time3>响应时间3

</response>

2.4 返回报文3

<?xml version="1.0" encoding="UTF-8"?>

<response id =”traceroutefinish” version=”0.1” flag=”1”><!--1成功,0失败-->

<source>源报文<source>

</response>

4. 各节点访问网站速度

3.1 发送报文

<?xml version="1.0" encoding="UTF-8"?>

<request id =”domainSpeed” version=”0.1”>

<url>

</request>

3.2 返回报文

<?xml version="1.0" encoding="UTF-8"?>

<response id=”domainSpeed” version=”0.1” flag=”1”><!--1成功,0失败-->

<downloadTime>下载时间</downloadTime> <speed>下载速度</speed> <size>网页大小</size>

</response>

5. 网页元素列表

4.1 发送报文

<?xml version="1.0" encoding="UTF-8"?>

<request id =”domainElementList” version=”0.1”>

<url>

</request>

4.2 返回报文1

<?xml version="1.0" encoding="UTF-8"?>

<response id =”domainElementList” version=”0.1” flag=”1”><!--1成功,0失败-->

<url> </url> <type>元素类型</type> <size>元素大小</size> <time>下载时间</time> <speed>下载速度</speed>

</response>

4.3 返回报文2

<?xml version="1.0" encoding="UTF-8"?>

<response id =”elementfinish” version=”0.1” flag=”1”><!--1成功,0失败--> </response>

6. 元素下载时间

5.1 发送报文

<?xml version="1.0" encoding="UTF-8"?>

<request id =”elementSpeed” version=”0.1”>

<url>

</request>

5.2 返回报文

<?xml version="1.0" encoding="UTF-8"?>

<response id =” elementSpeed” version=”0.1” flag=”1”><!--1成功,0失败--> <element>

<url>元素地址</url>

<type>元素类型</type>

<size>元素大小</size>

<time>下载时间</time> <speed>下载速度</speed>

</element>

</response>【用C编写一个XML格式的请求报文】

7. 网页各元素下载速度

6.1 发送报文【用C编写一个XML格式的请求报文】

<?xml version="1.0" encoding="UTF-8"?>

<request id =”AllElementSpeed” version=”0.1”>

<url>

</request>

6.2 返回报文

<?xml version="1.0" encoding="UTF-8"?>

<response id =” AllElementSpeed” version=”0.1” flag=”1”><!--1成功,0失败--> <element>

<url>元素地址</url>

<type>元素类型</type> <size>元素大小</size> <time>下载时间</time> <speed>下载速度</speed>

</element>

... ...

<element>

... ...

</element>

</response>

用C编写一个XML格式的请求报文(三)
HTTP的报文格式

POST /itx/itxsvc/param HTTP/1.1<0DH><0AH>【用C编写一个XML格式的请求报文】

HOST: 127.0.0.1:9080<0DH><0AH>

Accept: */*<0DH><0AH>

Accept-Language: zh-cn<0DH><0AH>

User-Agent: XAgent<0DH><0AH>

Connection: Keep-Alive<0DH><0AH>

Content-Type: application/x-

Content-Length: 929<0DH><0AH>

<0DH><0AH>

requestMessage=%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%3CTXLife%3E%3CUserAuthRequest%3E%3CUserLoginName%3Echangzhou%3C%2FUserLoginName%3E%3CUserPswd%3E%3CPswd%3Epassword%3C%2FPswd%3E%3C%2FUserPswd%3E%3C%2FUserAuthRequest%3E%3CTXLifeRequest%3E%3CTransRefGUID%3E0000010001%3C%2FTransRefGUID%3E%3CTransType+tc%3D%22208%22%3E%E8%B4%A6%E5%8D%95%E4%BF%A1%E6%81%AF%E6%9F%A5%E8%AF%A2%3C%2FTransType%3E%3CTransExeDate%3E2012-09-12%3C%2FTransExeDate%3E%3CTransExeTime%3E09%3A38%3A04%3C%2FTransExeTime%3E%3COLifE%3E%3CHolding+id%3D%22Holding_1%22%3E%3CPolicy%3E%3CApplicationInfo%3E%3CHOAppFormNumber%3E1234567890%3C%2FHOAppFormNumber%3E%3C%2FApplicationInfo%3E%3C%2FPolicy%3E%3C%2FHolding%3E%3C%2FOLifE%3E%3COLifEExtension+VendorCode%3D%221%22%3E%3CPartnerCode%3ECZ%3C%2FPartnerCode%3E%3C%2FOLifEExtension%3E%3C%2FTXLifeRequest%3E%3C%2FTXLife%3E&transType=208&tradingPartner=CZ&documentProtocol=CPIC_ECOM&bytesLength=591

【用C编写一个XML格式的请求报文】

其中<0DH><0AH>实际是换行符(有ComView程序为了显示,自动将回车换行转成的<0DH><0AH>的。)

应答的HTTP报文格式如下:

HTTP/1.1 200 OK<0DH><0AH>

Date: Wed, 12 Sep 2012 09:40:45 CST<0DH><0AH>

Server: XServer<0DH><0AH>

Content-Type: text/html<0DH><0AH>

Content-Length: 2380<0DH><0AH>

<0DH><0AH>

<TXLife><TXLifeResponse><TransRefGUID>0000000001</TransRefGUID><TransType

tc="208"/><TransExeDate>2003-12-04</TransExeDate><TransExeTime>13:52:30</TransExeTime><TransResult><ResultCode tc="1">Success</ResultCode><ResultInfo><ResultInfoDesc>ParaMedical Order Received</ResultInfoDesc></ResultInfo></TransResult><OLifE><Holding

id="Holding_1"><Policy><ProductCode>XXRR</ProductCode><PaidToDate>2012-10-12</PaidToDate><ModalPremAmt>20</ModalPremAmt><ApplicationInfo><HOAppFormNumber>4151235431</HOAppFormNumber></

ApplicationInfo></Policy></Holding><Party id="Party_1"><FullName>?92H><8BH>

</FullName><GovtID>321119197408194076</GovtID><GovtIDTC tc="10">

<81H></GovtIDTC><Person><Gender

tc="1">?94H>?/Gender><BirthDate>2002-03-31</BirthDate></Person><Phone

id="Phone_1"><PhoneTypeCode tc="12">绉诲<8AH>ㄧ<94H>

佃?9DH></PhoneTypeCode><DialNumber>9876543</DialNumber></Phone></Party><Party

id="Party_2"><FullName>寮犱?89H>宄?/FullName><GovtID>123456780912345</GovtID><GovtIDTC tc="10"><81H></GovtIDTC><Person><Gender

tc="1">?94H>?/Gender><BirthDate>2002-03-31</BirthDate></Person><Address

id="Address_1"><AddressTypeCode tc="17">Mailing</AddressTypeCode><Line1>骞垮?9EH>甯

<82H>渤璺?/Line1><Zip>510000</Zip></Address><Phone id="Phone_1"><PhoneTypeCode

tc="2">Business</PhoneTypeCode><DialNumber>1234567</DialNumber></Phone><Phone

id="Phone_2"><PhoneTypeCode

tc="1">Home</PhoneTypeCode><DialNumber>9876543</DialNumber></Phone><Phone

id="Phone_3"><PhoneTypeCode

tc="12">Mobile</PhoneTypeCode><DialNumber>9876543</DialNumber></Phone></Party><Relation OriginatingObjectID="Holding_1" RelatedObjectID="Party_1"

id="Relation_2"><OriginatingObjectType

tc="4">Holding</OriginatingObjectType><RelatedObjectType

【用C编写一个XML格式的请求报文】

tc="6">Party</RelatedObjectType><RelationRoleCode

tc="8">Owner</RelationRoleCode></Relation><Relation OriginatingObjectID="Holding_1" RelatedObjectID="Party_2" id="Relation_3"><OriginatingObjectType

tc="4">Holding</OriginatingObjectType><RelatedObjectType

tc="6">Party</RelatedObjectType><RelationRoleCode

tc="32">Insured</RelationRoleCode></Relation><Relation OriginatingObjectID="Party_1" RelatedObjectID="Party_2" id="Relation_4"><OriginatingObjectType

tc="6">Party</OriginatingObjectType><RelatedObjectType

tc="6">Party</RelatedObjectType><RelationRoleCode

tc="1">Spouse</RelationRoleCode></Relation></OLifE><OLifEExtension><PartnerCode>CZ</PartnerCode></OLifEExtension></TXLifeResponse></TXLife>

为了测试HTTP报文通信,我们准备如下:

1. 启动ComView.exe.并设置9080端口为监听端口

2. 运行TestDll.exe文件,并按下BtnSear按钮

3. 此时Comview中将显示如下:

4. 将Comview.exe中的监听端口关掉,将对方主机端口改成9080,,此时如下所示:

5. 运行B2biServ.exe,将查询应答报文修改成ResponeUTF(tc=208).xml,如下所示:

用C编写一个XML格式的请求报文(四)
嵌入式Web Server中XML数据发生器的设计与实现

  摘 要:在嵌入式Web服务器的开发中采用XML技术,可以为嵌入式系统管理提供统一的数据接口,降低系统开发的复杂度,有利于Web服务器的升级和维护。在分析HTTP1.1的基础上,设计出了一种嵌入式Web服务器,重点描述了Web服务器中XML发生器的设计方法。最后结合C语言编程,给出实例验证。

  关键词:XML;嵌入式系统;Web服务器;HTTP1.1
  中图分类号:TP393.09;TP368.1
  在嵌入式环境下,由于软硬件平台的多样性,在一个嵌入式应用中可能会存在多种不同的软硬件平台,而且随着嵌入式系统后续的不断改进和发展,其配置方案及控制接口可能会发生变化。此外,传统的嵌入式系统开发中,数据存储主要采用流式文件,程序对数据结构的依赖性强,不利于软件的升级和维护。在嵌入式系统中采用XML技术进行数据存储和处理可较好地解决上述问题。它可以用统一的接口来管理不同的设备接口及其相关操作,降低嵌入式系统部署、配置和升级的成本,提高了系统开发效率[1]。嵌入式Web服务器是实现嵌入式系统、设备以及应用之间互联的关键组成部分,已经成为目前嵌入式软件中的研究重点。本文将根据所设计的嵌入式Web服务器的方案,提出一种在嵌入式Web服务器中实现XML数据解析的方法,并对XML数据发生器模块进行重点介绍。
  1 嵌入式Web服务器的设计
  由于嵌入式设备的资源有限,一般来说嵌入式系统都没有文件系统或者TCP/IP协议栈(网络设备一般都有TCP/IP协议栈,但未必有文件系统),嵌入式存储设备和存储空间都非常小,要实现Web服务功能通常都比较困难。因此,针对上述问题,在分析HTTP1.1的基础上,结合嵌入式Web服务器的特点和要求,本文设计出的一种精简的嵌入式Web服务器结构如图1所示[2]。
  嵌入式Web服务器建立在安全套接口(Secure Socket Layer)上,HTTP或XML解析模块用于HTTP请求报文分析。如果HTTP 解析模块发现HTTP报文中的有XML消息,则该报文将由XML解析模块来处理;CGI环境变量模块主要用于定义操作系统的环境变量和程序执行环境,可以通过应用程序对这些变量进行存取。CGI函数模块、XML发生器模块以及本引擎模块都可以读取环境变量,并根据这些变量做出相对应的操作[3];CGI函数模块是一个HTTP函数,由HTTP解析模块负责回调[4]。XML数据发生器模块动态生成系统所需要的页面文件信息,用一种统一的、一致的手段来传递原先不统一、不一致的消息格式,增强系统内外部的交互能力,并降低开发成本。同时与系统的脚本引擎模块进行交互,提供统一数据接口。XML数据发生器模块也是本文重点研究的内容[5]。通过设计实现XML数据发生器功能,能够使得嵌入式 Web服务器支持XML数据,使得在不升级软件的情况下能够方便的更新页面内容和业务逻辑,实现嵌入式Web服务中的页面和业务逻辑动态分离的目标。
  2 XML概述
  2.1 XML的定义
  XML即为可扩展的标记语言(eXtensible Markup Language)。XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识。XML并非像HTML那样,提供了一组事先已经定义好了的标签,而是提供了一个标准。利用这个标准,开发人员可以根据实际需要定义自己的新的标记语言,并为这个标记语言规定它特有的一套标签[6]。
  2.2 XML的特点
  相对于HTML来说,XML具有先天的优越性。为了自己的浏览器增加一些特殊的显示效果,HTML加入了一些特殊的标记。日益增多的标签不但使得HTML越来越庞大,同时,浏览器的开发越来越复杂,还降低了不同浏览器之间的兼容性。尽管HTML的标签越来越多,其表现了却还远远不够,有了XML就可以自由地制定自己的标记。由于XML是非专有的并易于阅读和编写,就使得它成为在不同的应用间交换数据的理想格式。XML使用的是非专有的格式,不受版权、专利、商业秘密或是其他种类的知识产权的限制。同时,对于人类或是计算机程序来说,XML都容易阅读和编写,因而成为交换语言的首选。
  3 创建XML数据发生器
  3.1 基本思想
  跟CGI函数动态生成HTML文档一样,我们需要创建XML 数据发生器去动态生成XML文档。创建XML 数据发生器的过程与创建CGI函数的过程很类似,XML数据发生器的入口函数相当于CGI主函数,XML数据发生器入口函数同样也要注册到CGI全局变量cgi_entries中,这样在图1所示的Web服务器结构中,HTTP 解析模块发现用户请求XML文件时才能找到此入口,并利用XML数据发生器去动态生成XML文件。一般把XML数据发生器跟CGI函数放在同一个文件中。
  3.2 应用实例
  例如定义一个产生main.xml的数据发生器,主要步骤如下:
  (1)新创一个名为main.xml的文件
  (2)再新创一个文件main.c,在此文件中定义XML 数据发生器的入口函数
  其中put_page函数的定义如下:
  其中宏定义XML_PAGE为
  #define XML_PAGE “main.xml”
  (3)还有函数put_device_name、put_device_mode、put_hw_ver、put_fw_ver、put_host_name、put_login_user都是脚本device_name、device_mode、hardware_version、hardware_version、hostname、loginusername的处理函数。
  (4)在cgi_entry.c注册这个函数,即在cgi_entries数组中加入如下语句:
  {"main.xml", 0, main_xml},
  并在cgi_entry.h中声明这个函数为外部函数:
  extern int main_cgi(httpd_cond * http_cond);
  完成以上编码后,进行编译、执行,可以测试Web服务器中的XML数据发生器模块是否正常工作。
  4 结束语
  本文介绍了一种嵌入式Web服务器的结构,重点描述了结构中XML数据发生器的实现方式。测试表明:Web服务器端能够正确的输出动态XML文件。本文所介绍的开发方法,使得嵌入式系统的动态界面开发更加方便快捷。由于程序设计时注重了数据内容与其结构的独立,因此即使界面元素发生变化,程序也无需作大量改动,降低了开发和维护成本。
  参考文献:
  [1]马毅,高岭,张林.嵌入式Web服务模型的设计及初步实现[J].计算机技术与发展,2009.19(1):29-31.
  [2]徐兵,沈玉利,谢仕义.嵌入式Web服务器端脚本引擎设计与实现[J].计算机工程与设计,2008,29(15):3933-3935.
  [3]刘利群,谢仕义.嵌入式 Web 服务器端文件系统的设计与实现[J].计算机工程与设计,2009,30(12):2859-2861.
  [4]张曦煌,柴志雷.嵌入式web服务器中CGI的特点及实现[J].小型微型计算机系统,2003,24(11):2046-2047.
  [5]雷涛,郝福珍.嵌入式Web Server的研究与实现[J].计算机工程与设计,2006,27(16):2992-2994.
  [6]高觐悦,张功萱.嵌入式XML解析器的设计与实现[J].苏州市职业大学学报,2009,20(1):66-69.
  作者简介:于北瑜(1969-),计算机科学与应用专业,研究方向:软件和计算机网络。
  作者单位:广东海洋大学信息学院,广东湛江 524088

用C编写一个XML格式的请求报文(五)
基于ZeroMQ&JSON的分布式测控系统消息通信架构设计

  摘 要: 为了提高异构环境下的分布式测控系统内部网络的通信效率,采用消息中间件技术和一种轻量级的数据交换格式,设计了一种有效的分布式测控网络消息通信架构。该架构用在智能楼宇监控实验中,提高了数据的传输效率。该架构解决了异构系统集成的困难以及其数据交换格式的选择问题,经过实践的检验,该框架切实可行,可以胜任不断变化的环境和任务要求,具有广泛的适用性和良好的应用性。

  关键词: 消息中间件; ZeroMQ; 消息管道; 消息通信架构
  中图分类号: TN911?34; TP273.5 文献标识码: A 文章编号: 1004?373X(2014)02?0105?05
  0 引 言
  分布式测控系统通常由多个测控部件及其接口电路构成。各功能相对独立的测控部件及其电路被称为系统节点功能模块,构成相对独立的数据采集系统。每个节点只需完成系统的部分功能,而所有节点协同工作则可完成测控系统预期的全部功能。
  目前的测控系统,大多采用基于单片机的传感器无线组网或者采用工业现场总线的有线组网形式,受限于单片机的处理能力、所处环境的电磁兼容性以及总线组网通信能力的约束,网络阻塞、数据的传输过程中丢失数据以及实时性问题尤为突出。
  由于测控任务和测控环境在不断的向复杂化、大型化方向发展,测控系统的监控对象越来越复杂,越来越分散,信号采集终端呈现分布式趋势。在整个系统中,由于各台仪器与设备种类繁多,硬件平台各异,软件环境也各不一致,所需要的控制命令、数据报文的格式也不统一,使得系统的灵活性很差,一旦对设备重新部署,就会大范围改动软件通信中的报文格式,导致系统可靠性较差,维护困难。
  随着大量带有嵌入式操作系统的控制设备的应用和工业以太网络环境的不断完善,集成WSN和多种现场总线的网关的大量应用,整个系统对数据的处理能力和通信能力得到很大的提高,为消息中间件技术应用提供了良好的硬件平台,该技术是一种由消息传送机制或者消息队列模式组成的中间件技术,利用该技术可以进行平台无关的数据通信,并利用数据通信对各个设备进行分布式系统集成,而且在嵌入式多任务操作系统的支持下,可以扩展为进程间的数据通信。
  以往的系统中,为了避免数据在通信中丢失,数据的发送方需要专门等待已发送的消息的回复,不利于多任务的并发。而消息中间件技术具有异步工作的特性,发送方可以发送数据到消息中间件后,无需等待,直接处理其他任务,由消息中间件来确保数据被接收方完整接收,对于系统中设备之间工作速率不同步,不会影响系统数据传输的稳定性和可靠性。消息中间件实现了整个系统的互联,确保系统安全、可靠、实时的工作。
  目前消息中间件主要采用两种消息处理模型:点对点模型和发布/订阅模型[1]:
  点对点模型是一种基于连接的模型。消息发送方(生产者)和消息接收方(消费者)在进行通信时必须维持一条数据链路的连接,生产者将消息发送到消息队列(生产),该消息将一直保留到被消费者从队列中提取(消费)或者消息过期为止。这种模型既支持异步消息传送模式,也支持同步请求/应答模式。
  发布/订阅模型是一种基于推送的模型。消息发送方(发布者)和消息接收方(订阅者)采用透明的形式进行通信,发布者和多个订阅者都会被注册到消息通道上,消息通道一旦接收到消息,会主动地调用注册在通道中的订阅者,进而完成对消息内容的消费。这种模型既支持广播机制,可以将一条消息传递给多个订阅者,也支持抢占机制,同一时间只能有一个消费者处理该消息。
  由于发布/订阅模型的消息主动推送特点,使得它成为现代分布式计算环境的理想选择。
  1 ZeroMQ&JSON的特点
  分布式计算环境需要处理大量的网络通信,分布式测控系统中需要解析大量的控制命令、数据报文。
  1.1 ZeroMQ
  在分布式系统通信网络中,进程间的交互所使用的API实际上是封装了TCP/IP协议的Berkeley套接字(BSD)SOCKET,在基于Socket API开发TCP通信程序时,需要处理很多网络异常(比如连接异常中断以及重连),为了提高通信性能,往往进行异步(非阻塞)、缓冲区、多线程之类的优化,这些都极大地增加了通信程序的开发难度。
  为了适应系统中的各个节点分散在分布式系统间,ZeroMQ被设计成网络协议栈中的一个可伸缩层,不仅仅是一个点对点交互,还定义了适应于分布式系统的全局拓扑以便于在多个线程、内核和主机盒之间弹性伸缩[2]。
  ZeroMQ是一个开源的、跨平台、高性能、精简灵活的网络消息中间件,将操作系统的异步、消息缓冲区和多线程处理机制封装在内,对各种套接字类型(如进程内通信、IPC、TCP和UDP)、网络连接建立、数据打包成帧、路由选择等底层网络通信行为进行了抽象,ZeroMQ可以自动感知路由和网络拓扑,灵活地支持多种通信环境[3]。
  ZeroMQ主要支持 4 类通信模式:请求应答模式、发布/订阅模式、管道模式以及信号模式, 其中前3种模式使用较多,信号模式使用较少,主要是用来支持传统的TCP Socket 点对点模型。
  相对于同类中间件MSMQ、ActiveMQ和RabbitMQ在部署时需要专门的一个服务器,ZeroMQ只需要让应用程序引用ZeroMQ程序库,就可以在多个进程间进行消息发送,使得部署起来非常简单。
  ZeroMQ采用 C/C++ 开发,并且协议格式定义得很简洁,所以性能远远高于其他的消息中间件,如图1所示[4]。缺点是ZeroMQ被设计成侧重于消息传输的轻量级消息中间件,缺少消息服务器来存储和转发消息,所以不支持消息持久化及崩溃恢复。
  
  图1 MSMQ、ActiveMQ、RabbitMQ和ZeroMQ的消息传输性能对比   根据ZeroMQ给出的测试报告,对于一个长度为120 B的消息,在1 Gb Ethernet网环境下,消息的传输可达到900 Mb/s,完全满足系统的实时性要求。
  1.2 JSON
  由于各种测控节点平台的异构性,需要一个格式统一、跨平台的数据交换格式以方便对系统中的命令、数据报文进行解析。JSON和XML是目前网络中最常用的两大数据传输格式。XML是一种标记语言,用于结构性标记电子文件,可以用来标记数据、定义数据类型,允许用户自定义标签,用于传输和存储数据。DOM是对XML文档进行应用开发、编程的应用程序接口,把XML文档作为树结构来查看,能够通过DOM树来访问所有元素(节点),可以修改或删除节点的内容,并创建新的节点,因此,可以把XML看成是一种数据结构或者是一种虚拟数据库。
  XML文件中存在很多用于解析的附加信息,由于XML最初是用于在WEB中传输大数据,解析信息在整个文件中所占比例较小。然而分布式测控系统中,需要解析的命令、数据报文都是一些小数据,使得XML文件变的很臃肿,因此XML在小数据上的传输、存储的效率上存在一定问题。JSON也是基于纯文本的数据格式,旨在传送基于文本的数据,支持的数据结构为:名称/值对集合,其对象格式如图2所示。
  
  图2 JSON对象包装格式
  以一个命令的JSON和XML格式作为对比,例如一条移动显示组件窗口的命令。
  如表1所示,相对于复杂的XML数据格式,JSON格式简单,易于读写,用于解析的信息格式压缩,内存占用小,传输速度快,对JSON的解析效率高。在存取速度上,JSON是XML的2.3倍左右,而JSON文件的大小则为XML文件的[12]左右[5?6]。
  表1 JSON与XML格式对比
  2 系统的总体结构
  对于多数分布式测控系统而言,基于ZeroMQ和JSON的测控技术更加容易实现系统功能的集成。下面以一个具有普遍意义的分布式测控系统为例,介绍这种系统集成方法的应用。
  整个测控系统体系结构如图3所示,根据功能分成4个层次:
  (1) 物理设备层:负责现场数据(模拟量、数字量、图像)采集以及预处理、接受控制指令输出控制量(模拟量、开关量等),主要包括数据采集器、
  传感器节点、控制器节点、接口板和摄像头组成,由支持嵌入式操作系统的嵌入式CPU、存储单元、网络通信单元、传感器和相关总线接口组成。
  (2) 操作系统层:在裁剪并移植操作系统的基础上,利用其提供的多进/线程机制、网络通信协议栈,通过移植相关的嵌入式数据库、ZeroMQ和JSON等开源软件库,完成相关监控软件的开发,包括:数据采集与处理、数据存储、控制量输出和远程数据/指令传输。
  (3) 分布式平台的中间件层:基于ZeroMQ和JSON机制,由消息管理模块、链路搜索模块和群组管理模块组成,构成一个分布式的通信网络的通信接入服务器。该服务器作为TCP/IP通信的服务器端,通过ZeroMQ的发布/订阅模型,与物理设备层模块、基础组件层模块通信,负责接收、分发和应答这两层中模块的消息,为了在不同平台之间进行数据交换,通过JSON机制对命令、数据报文进行封装。
  
  图3 分布式测控系统结构示意图
  (4) 基础设施组件层:用户应用平台,由各种显示组件、输入/输出、控制策略、Web组件和数据库组件构成,以图形化界面实现与分布式测控系统的交互。
  如图4所示,每一层由实体(物理硬件或软件)组成并进行封装和抽象,上层能够接受下层提供的服务,并通过封装能向上层提供增值服务[7]。
  图4 基于ZeroMQ和JSON集成的分布式测控系统模块
  3 系统的通信模型实现
  在分布式测控系统中,由于参与测控的各个物理设备分布在不同的节点中,需要建立一条从一个信号源端点到一个或多个控制节点的、虚拟的、逻辑的、非物理电路连接的数据传输通道,可以抽象的认为是一条信息管道。分布式测控系统的信息集成就是根据测控系统的功能要求,用若干条虚拟的信息管道将系统各节点中的相关信息端点在逻辑上连接起来,从而实现分布式测控系统的信息集成[8]。通信服务是整个分布式测控系统的信息入口,消息中间件是分布式消息系统的核心。借助“异步处理”、“保存并转发”及“保证传送”机制,消息中间件为通信服务稳定高效的运行提供了有力的支持。
  3.1 基于ZeroMQ分布式消息服务
  ZeroMQ的实现就是提供一个运行在代理服务器上的通知服务以及一组支持客户端应用开发与运行的接口库。面向对象中间件能够屏蔽底层分布环境的复杂性和异构性,实现异构网络环境下的分布应用软件之间的互连、互通和互操作,提高系统的可移植性。分布式消息系统服务采用ZeroMQ提供的REQ?REP模式、PUB?SUB模式来支持不同的消息传输方式:
  REQ?REP模式:由请求端(REQ)发起请求,并等待回应端(REP)响应请求,该模式是一个同步的双向通信,应用于数据采集、控制输出等实时性要求高的通信上。
  PUB?SUB模式:发布端(PUB)是单向发送消息,订阅端(SUB)则只负责接收消息,中间不能反馈,PUB和SUB可以是1∶N,如图5所示。如果订阅端连接成功,ZeroMQ会确保发布端发布的信息不会丢失。该模式是一个异步的通信,应用于命令发布,数据显示等一般性的通信上。
  使用PUB?SUB模式,消息的生产者和消费者之间没有耦合,订阅者和发布者可以在运行时动态添加,不干扰各子系统正常运行。由于指令具有强制执行性,需要确保指令的接收者能够接收到数据,这就需要用到REQ?REP的消息队列模式。   
  图5 ZeroMQ提供的PUB?SUB模式和REQ?REP模式
  3.2 分布式测控系统通信架构
  一个完整的消息系统可以称为一个“消息网”,网内包含不同的节点,这些节点分布在不同主机的不同进程中。通信架构图如图6所示。
  在整个系统的消息通信架构中,最重要的就是消息管理,该模块负责和节点端系统通信,作为TCP/IP通信的服务器端。
  负责接收各种节点端的消息,并利用信号源管理模块中的信号源节点和显示组件节点、控制节点之间的对应关系,分送客户端消息到PC架构子系统,分布式子系统,和总线式子系统中去。具体功能包括:
  (1) TCP通信服务器:利用ZeroMQ提供的发布/订阅模式负责和客户机通信,具有灵活的可扩展机制;
  (2) JSON协议适配器:负责将节点端过来的JSON指令解析成各种调用,并将结果数据JSON传送给TCP服务器分发给节点端;
  (3) 消息分发处理:根据消息类型经适配器转换后,对群组信息进行搜索得到最短路径,向其他各种组件分发的控制指令/数据。
  在分布式测控系统中一次典型的消息通信过程如下:首先,客户端组、数据库组件、控制台组、信号源组、控制组、控制器组合显示组订阅到消息系统中;其次,由客户端“发布”建立一条从信号源——控制策略——输入/输出——到控制节点链路的指令,各群组组件“订阅”到这个指令后,创建各自的线程,在线程中根据传入的IP地址和端口号建立相应的通信连接;最后,控制台组件根据从信号源“订阅”到的传感器监测数据,依据设定的控制策略,与控制节点进行“请求/响应”通信,控制节点按照指令进行有效的控制。
  为了测试整个消息系统的性能,在1 Gb Ethernet网络环境下,通过服务器连续“发布”JSON封装的、长度为100个字节的“命令”指令1 000 000条,各群组组件全部成功的“订阅”,没有发生“命令”丢失现象,平均延时<10 μs,满足系统的实时性要求;在摄像头采集、传送和显示组件显示一帧D1图像(702×576),平均延时大约<20 ms,满足视频实时传输显示要求,全部的测试结果验证了消息系统的高效性。
  4 结 论
  本研究结合传感器网络、嵌入式计算、分布式信息处理、网络通信等先进技术,本文创新之处在于提出了一种基于消息中间件的测控网络中的消息通信架构,提高了通信系统的消息传递能力、系统的稳定性和数据的安全性。
  通过在各节点之间建立虚拟信息管道,实现具体物理连接链路节点信息集成,采用该消息通信架构的分布式测控网络具有智能化、适应不同环境要求、可靠性好、效率高和易于扩展等特点, 可满足多种不同环境的工业测控任务要求,具有良好的应用前景。
  参考文献
  [1] 李易民,凌捷.安全消息中间件的设计[J].计算机工程与设计,2011,32(6):1934?1937.
  [2] 蒲凤平,陈建政.基于ZeroMQ的分布式系统[J].电子测试,2012(7):24?29,33.
  [3] HINTJENS Pieter. Code connected volume 1,learning ZeroMQ [EB/OL]. [2013?07?27]. http://www.ppurl.com/2013/07/code?connected?volume?1?learning?zeromq.
  [4] Julien. ActiveMQ or RabbitMQ or ZeroMQ or ActiveMQ [EB/OL]. [2009?04?08]. http://stackoverflow.com/questions.
  [5] 陈京,陈容红,江志农.设备故障监测诊断平台多语言技术研究[J].电子设计工程,2012,20(11): 5?7,11.
  [6] 高静,段会川.JSON数据传输效率研究[J].计算机工程与设计,2011,32(7):2267?2270.
  [7] 易勇,曾家智,古天祥.实时构架的分布式测控系统[J].电子测量与仪器学报,2006,20(3):75?79.
  [8] 陈非凡.基于信息管道技术的分布式测控系统集成方法[J].清华大学学报:自然科学版,2010(8):1229?1233.

用C编写一个XML格式的请求报文

http://m.zhuodaoren.com/fanwen296393/

推荐访问:xml报文解析 用c语言编写一个心形

模板推荐文章

推荐内容

上一篇:规范书写的好处规范文 下一篇:LISP快速展点程序