过程自动化MES系统中报文的处理方法

2019-09-09 08:14王峥牛盂杰张莹李晓东
数码世界 2019年5期
关键词:报文

王峥 牛盂杰 张莹 李晓东

摘要:论述了一种MES中报文的处理方法,包括报文封装类设计,通讯接口设计,数据库设计等内容。描述了.net框架下端口监听及stream流传输的程序设计方法。

关键词:mes 报文 socket 端口监听 stream流

本文阐述了一种基于socket协议的MES二级系统报文的处理方法。报文是MES系统普遍采用的信息传输方式,具有组成灵活,传输可控,解读方便的特点。设计报文的处理方式,是MES系统重要的组成部分。本项目是一个镀锡线电控系统的MES二级子系统运行稳定,传输可靠。在此简单阐述—下报文的处理方法。

报文处理方法包含以下几个主要环节

1,定义钢卷钢种数据信息PDI,此类主要用于生成报文的各种参数。报文处理需要的元素,都封装成类,再进行实例化调用,这样程序的代码重用及组装都很方便。

public class PDI

{

public int flag{ get; set;}∥钢种标志

public int ID{ get; set;}∥钢种ID

public string Schedule_Code{ get; set;}∥计划代码

private string _coil_no一…I;∥私有变量卷号

pulolic string Coil_NO∥对私有变量的getter和setter操作

{

get

{

if (!string.IsNullOrEmpty(_coil_no》

return _coil_no.ToUpper();

else

return””:

l

set{ _coil_no - value;}

}

public string Schedule_Type{ get; set;}//,//各种钢卷属性的操作方法

public string RepairFlag{ get; set;)

public string Repair_Type{ get; set;}

public int IsDummy{ get; set;}

}

2,报文定义类,此处定义报文封装类,包括各种操作属性,比如ID,生产线代码,请求时间,回应时间,状态,发送目标,回答目标,报文主体内容等。此报文将进入报文池,以队列方式,先进入池的报文,被先处理发送。

public class DBMAILBOX

{

public int ID{ get; set;}∥///报文队列代码

public int Plant_ID{ get; set;}

public int RequestNo{ get; set;}

public DateTime RequestDate{ get; set;}

public DateTime ReplyDate{ get; set;}

public int Status{ get; set;}

public string SendTo{ get; set;}

public string ReplyTo{ get; set;}

public int IDM{ get; set;}厂/∥报文标志代码

public byte[l Msg{ get; set;}////报文内容

publicbyte[l MsgReply{ get; set;}

}

3,组合报文体框架,此处生成报文体对象,根据报文种类(即IDM报文标志),调用对应的报文生成方法,返回报文内容,与其他属性构成报文主体,进入数组,形成报文队列。

DBMAILBOX m—new DBMAILBOX();/////报文对象

m.Plant_ID -0;

m.IDM -2965;∥/∥//新生成的报文为2965

m.Msg—msg.MSG2965(p,setup);/‘∥//报文生成方法,返回报文内容

m.SendTo -”L1C”;/////////报文发送属性

m.RequestDate - DateTime.Now;

m.Reply_Date - DateTime.Now;

m.ReplyTo -llL2Serverll;

m。Status -0:

mail.Add(m);////////把报文内容加入数组mail,形成报文队列。

4,组合报文体,此处形成报文内容,不含其它属性,只是整个报文.dlomailbox的msg部分,也就是向一级系统实际发送的报文内容。

public Byte[]MSG2965(int intMSGPORl, intintMSGPOR2)///////

{

this.MSG_ID - 2965;////報文ID

this.MSG_I。EN—l6;///////报文长度,第一次赋值,作用是电文体开始赋值的位置,2965电文的卷号的开始位置为16,下面的循环中,根据this.MSG_I。EN的初始值,开始给电文体赋值,MSGLEN也不断增加

this.SetString(p.Coil_NO,20,l l,0);///////向电文体写入string

str - DoString.toLongString(str, len,f,itype);////DoString是静态类,将str补充到len长度(不

足时),此时str是Coil_NO卷号,保证卷号长度固定

//////以下是报文各段属性赋值,简略

this.SetSwapValue《Int16)intMSGPORl);/////向电文体写入开卷机请求数据l

this. SetSwapValue《Int16)intMSGPOR2);/////向电文体写入开卷机请求数据2

return this.GetBytes();/////加上报上报头head(最终调用sethead0方法),形成最终报文体

}

5,socket端口监听类。本项目采用socket方式接收和发送电文,通过不同端口进行收发,提高了报文处理速度。利用.NET框架的socket封装类,简化了程序代码。采用多线程方式,对收发动作进行新建线程方式,实现并发处理。.NET框架用IPEndPoint对象来表示一个特定的IP地址和端口的组合,应用该对象的场景多是在将socket绑定到本地地址。

∥接收来自L1-级系统的报文

public class MsgFromLI:ThreadService////建立线程

{

public ThreadStatus status—null;

TcpListener server=null;///////定义监听类的对象

IPEndPoint ipLocalEndPoint=null;

pulolic MsgFromLl()///构造函数,进行初始化,建立监听通道

{

ipLocaIEndPoint - newIPEndPoint(IPAddress.Parse("10.36.1.225"), 3001);

//∥监听一级系统PLC的ip和端口

status—new ThreadStatus();////建立线程状态对象

public void Start0

{

status.run_flag - true;

server - new TcpListener(ipLocalEndPoint);//,//监听类实例化

server. Start();//∥启动监听

status.starttime - DoDateTime.getNovrString();

TcpClient client—null;

while (status.run_flag)

{

if (client一一null』!client.Connected)

{

client - server.AcceptTcpClient();////開始接收请求

client.ReceiveBufferSize -2016;/∥//接收缓冲区长度

}

client.ReceiveBufferSize - 2016;

ByteLl bytes - new Byte[client.ReceiveBufferSizel;//接收报文的字符串初始化

NetworkStream stream — client.GetStream();/∥//建立stream流,进行传输

stream.Read(bytes,O,bytes.Length);////读入stream流数据进入字符串

client. Close();

client—null;

}

}

}

6,发送报文

public void Start0

{

status.run_flag - true;

status.start_time - DoDate-Fime.getNo.nrString();

string rernoteIP~"10.36.1.135";////socket客户端连接远程服务器地址

int remotePort - 3003;

string localIP一"10.36.1.225";

int localPort - 2003;

MSGTcpClient client - nevr MSGTcpClient(localIP. localPort, remoteIP, remotePort);

DBMAILBOX msg—new DBMAILBOX();

while (status.run_flag)

{

if(! client. Connect(》/////client初始化要建立连接

{

Thread.Sleep(2000);

continue:

}

msg -Scan();//∥//msg存人扫描的信息结果,形成电文

msg.Status一1;∥∥/msg不为空

client.SendOnce(msg.Msg.0,2016);//,//发送电文,

∥∥/上面msg -Scan();//∥//IIlsg存入扫描的信息结果,形成电文

}

}

发送动作语句

public Boolean SendOnceCoyte[l buffer .int offset,int size)

{

stream一client.GetStream();//

∥返回用于发送和接收数据的System.Net.Sockets.NetworkStream。

stream.Write(buffer, offset.slze);//∥向stream的对端发出数据

return true;

}

猜你喜欢
报文
海法新港一期自动化集装箱码头电子数据交换报文系统设计与实现
基于报文类型的限速值动态调整
基于用户和电路的攻击识别方法
基于Python的网际校验和算法的实现
AIS欺骗性干扰分析及对策研究
TCP/IP协议安全分析仿真平台设计
基于HTTPPOST报文算法分析
从预报报文获取农气预报程序设计浅谈
大数据背景下数据中心VXLAN技术的应用
用户设备进行组播路径追踪的方法及系统