基于HTTP协议的数据传输程序设计与实例

2022-01-20 01:39于文学毕聪瑞陈绍飞
工程与试验 2021年4期
关键词:服务端程序设计客户端

于文学,张 鹏,毕聪瑞,陈绍飞

(中机试验装备股份有限公司,吉林 长春 130103)

1 引 言

自动校直机现已成为工厂中不可或缺的智能装备,代替人工操作液压机等设备完成校直工序,降低人工劳动成本及时间成本,实现自动校正,使产品能够满足使用要求,极大地提高产品的利用率。随着“数字化工厂”概念的诞生,工厂中的加工产品各工艺数据追溯显得尤为重要,自动校直机同样面临着校正数据及设备运行状态实时传输的问题。

目前,工厂MES系统数据采集方式可分为以下三类:直接联网通信进行数据交互、通过工业网关通信进行数据交互、远程IO模块进行数据交互。直接联网通信适用于生产设备具备以太网通信网口,直接与局域网连接进行数据传输。工业网关通信适用于生产设备不具备以太网通信网口硬件条件,通过PLC模块进行数据采集。当生产设备既不具备以太网通信网口,也没有使用PLC模块,可增加远程IO模块进行数据采集。

基于HTTP协议进行数据传输属于直接联网通信的一种主流方式。HTTP协议具有简单快速、灵活、可扩展性强的特点,适用于工厂内MES数据交互的应用场景。因此,本文介绍了一种基于HTTP协议进行数据传输的方法,与自动校直机上位机程序相融合,能够快速地完成数据信息交互流程。

2 HTTP协议

2.1 HTTP协议及工作流程

HTTP协议中文名为超文本传输协议,是一个基于请求与响应模式的、无状态的、应用层的协议,以TCP协议为基础进行数据传输[1,2]。

HTTP服务端启动服务并侦听HTTP客户端请求,客户端封装请求头、请求体后发出请求。服务端侦听到客户端请求后进行解析并处理,封装响应头、响应体,返回响应消息,完成一次客户端与服务端信息交互流程。HTTP协议工作流程如图1所示。

图1 HTTP协议工作流程

2.2 HTTP协议常用方法

(1)GET方法。获取服务器上的某一特定资源,请求的数据信息附加在服务器接口路径之后,以“?”分割URL和传输数据,多个参数用“&”连接[3]。传输的数据大小受URL长度限制,少量的数据传输适宜采用GET方法进行资源请求。

(2)POST方法。向服务器提交资源让服务器处理,比如提交表达、上传文件等。请求的数据放置在HTTP请求包的包体中,理论上传输的数据大小不受限制。

(3)PUT方法。向服务器发送请求。如果URL不存在,服务器根据请求创建资源;如果URL存在,根据请求修改URL资源[4]。

(4)DELETE方法。请求服务器删除某一特定资源。

2.3 HTTP协议特性

(1)安全性

HTTP协议安全性较差。HTTP协议属于明文传输协议,数据交互过程没有进行任何加密及通信认证。GET方法更是将请求的数据信息完全显示在URL路径之后,无需任何数据解析便可直接获取请求数据内容。若对数据安全性要求较高,不建议使用HTTP协议,可采用HTTPS协议实现。

(2)可靠性

HTTP协议基于TCP协议进行数据传输。TCP协议是一个连接传输协议,因此HTTP协议数据传输可靠性较高。

(3)灵活、扩展性

HTTP协议对于报文没有太多限制,可根据实际情况灵活扩展,程序改动量较小。

3 基于HTTP协议的上位机程序设计与实例

自动校直机传输的数据主要分以下两部分:一部分为设备实时状态数据,另一部分为产品加工数据。保持着程序高内聚、低耦合的设计思想,将上位机程序设计成既是服务端,又是客户端。服务端负责监听MES系统请求,将设备实时工作状态数据进行封装,作为请求响应返回给MES系统。客户端通过POST方法向MES系统服务器发送产品加工数据,实现产品校直工艺数据的可追溯功能。根据上述设计思想,程序设计流程如图2所示。

图2 程序设计流程图

上位机程序在.NET Framework 4.5框架上进行开发,工程项目引用System.Web.dll,并添加System.Net、System.Web命名空间。

3.1 HTTP服务端程序实例

(1)启动服务端

通过以下方式启动服务器:

//port为服务端侦听端口

listener = new TcpListener(port);

listener.Start();

(2)解析客户端请求并响应

服务端调用AcceptTcpClient()侦听客户端请求。

public void process()

{

Task.Factory.StartNew(() =>

{

inputStream=

new BufferedStream(socket.GetStream());

outputStream = New StreamWriter

(new BufferedStream(socket.GetStream()));

try

{

parseRequest();

readHeaders();

if (http_method.Equals("GET"))

handleGETRequest();

else if (http_method.Equals("POST"))

handlePOSTRequest();

}

catch (Exception e)

{

Console.WriteLine("Exception: " + e.ToString

());

writeFailure();

}

outputStream.Flush();

inputStream = null;

outputStream = null;

socket.Close();

});

}

上述程序Socket变量为AcceptTcpClient()的返回值,通过以上程序可完成客户端请求方法及对数据进行解析。

3.2 HTTP客户端程序实例

客户端程序主要调用GET方法与POST方法进行资源请求与发送。HttpWebRequest类属性设置如下:

KeepAlive属性:客户端设置是否与服务端建立持续型连接,默认值为true。

Method属性:客户端设置请求的方法,默认值为GET。

ContentType属性:客户端设置HTTP标头的数据格式,默认值为null。

Timeout属性:客户端设置请求超时前等待的毫秒数,默认值为100s。

(1)GET方法程序

public static string Get(string Url)

{

HttpWebRequest getrequest = (HttpWebRequest)

WebRequest.Create(Url);

getrequest.Proxy = null;

getrequest.KeepAlive = false;

getrequest.Method = "GET";

getrequest.ContentType =

"application/json; charset=UTF-8";

getrequest.AutomaticDecompression = DecompressionMethods.GZip;

getrequest.Timeout = 2 * 1000;

HttpWebResponse getresponse =(HttpWebResponse)

getrequest.GetResponse();

Stream myResponseStream

getresponse.GetResponseStream();

StreamReader mygetStreamReader = new

StreamReader(myResponseStream, Encoding.UTF8);

string retgetString =

mygetStreamReader.ReadToEnd();

mygetStreamReader.Close();

myResponseStream.Close();

if (getresponse !=null)

getresponse.Close();

if (getrequest !=null)

getrequest.Abort();

return retgetString;

}

(2)POST方法程序

public static string Post(string Url, string Data, string Referer = null)

{

HttpWebRequest postrequest =

(HttpWebRequest)WebRequest.Create(Url);

postrequest.Method = "POST";

postrequest.Referer = Referer;

byte[] bytes = Encoding.UTF8.GetBytes(Data);

postrequest.ContentType =

"application/x-www-form-urlencoded";

postrequest.ContentLength = bytes.Length;

postrequest.Timeout = 2 * 1000;

Stream myResponseStream =

postrequest.GetRequestStream();

myResponseStream.Write(bytes, 0, bytes.Length);

HttpWebResponse postresponse =

(HttpWebResponse) postrequest.GetResponse();

StreamReader mypostStreamReader = new

StreamReader(postresponse.GetResponseStream(), Encoding.UTF8);

string retpostString =

mypostStreamReader.ReadToEnd();

mypostStreamReader.Close();

myResponseStream.Close();

if (postresponse != null)

postresponse.Close();

if (postrequest != null)

postrequest.Abort();

return retpostString;

}

3.3 开发注意事项

(1)服务端调用AcceptTcpClient()会阻塞线程执行,直至客户端发起请求。可在调用AcceptTcpClient()前调用Pending()判断当前是否存在挂起的连接请求。若存在则调用AcceptTcpClient()获取请求数据,若不存在则等待下一次轮询。具体代码如下:

While(true)

{

if(tcpListener.Pending())

tcpListener.AcceptTcpClient();

}

(2)服务端处理连接请求时可能耗时较长,由于自动校直机各轴位置控制对实时性要求较高,本程序采用任务模式进行数据处理,Action为连接请求处理函数Task.Factory.StartNew(()=>Action)。

4 结 论

本文详细介绍了基于HTTP协议进行数据传输的程序设计与实例。上位机采用C#程序开发,使用HTTP协议传输数据极大减少了复杂的通信协议开发流程,程序简洁、可读性高、可扩展性强,而且设计周期短,数据传输效率高。目前现场的应用情况表明,系统稳定可靠运行,可以广泛地应用到其他设备上,为MES数据传输提供了一种新的可靠传输方式。

猜你喜欢
服务端程序设计客户端
基于Visual Studio Code的C语言程序设计实践教学探索
如何看待传统媒体新闻客户端的“断舍离”?
从细节入手,谈PLC程序设计技巧
县级台在突发事件报道中如何应用手机客户端
孵化垂直频道:新闻客户端新策略
新时期《移动Web服务端开发》课程教学改革的研究
在Windows Server 2008上创建应用
高职高专院校C语言程序设计教学改革探索
PLC梯形图程序设计技巧及应用
摸清黑客套路防范木马侵入