在自动化系统中,与各种设备进行通信是至关重要的。这些通信协议通常由基于字符串或结构的数据包组成。虽然基于结构的数据包更容易解析其内容,并且可以比基于字符串的数据包更小,但由于基于字符串的数据包在异构系统中具有更好的兼容性,因此在通信系统中经常使用基于字符串的数据包。本文介绍了一种具有解析和队列功能的消息数据包管理器。
将记录定义为数据包的单位,记录包含多个字段。例如,可以将基于结构的数据包转换为基于字符串的数据包,如下所示:
struct EQP_Cleaner {
char ID[5];
RGB color;
int part_number;
int duration;
}
转换为基于字符串的数据包:
<EQP_CLEANER ID=EQP01 color=RED part_number=80 duration=100/>
可以通过简单的代码定义消息格式,并使用以下方法来设置队列和处理数据:
消息数据包描述了由记录名称和字段集组成的记录。记录和字段的结构如下:
public class Field {
public String name;
public String value;
}
public class Record {
public String name;
ArrayList<Field> Fields = new ArrayList<Field>();
public int size() {
return Fields.size();
}
}
以下是一些关键方法的描述:
void setQsize(int size) - 设置缓冲区存储消息数据包的最大大小
int size() - 获取当前缓冲区存储的消息数据包数量
void clear() - 清空缓冲区
void addField(Record t, Field f) - 向记录添加字段
void addRecord(Record t) - 向缓冲区添加记录
Record getRecord(int index) - 通过索引获取缓冲区中的记录
Record getRecord(String name) - 通过名称关键字获取记录
Field getField(Record t, int index) - 获取指定记录中的字段
Field getField(Record t, String name) - 通过名称关键字获取指定记录中的字段
Record deleteMessage(int index) - 删除指定索引的记录
Record deleteMessage(String name) - 通过名称关键字删除记录
Record popMessage() - 获取并删除缓冲区中最旧的记录
void pushMessage(String strLine) - 将记录插入缓冲区,记录将通过解析字符串消息填充。如果当前缓冲区大小大于最大存储大小,将删除最旧的记录。
pushMessage(..) 方法同时实现了解析字符串消息并将其推送到缓冲区存储的功能。
public void pushMessage(String strLine){
int bracket_start=0;
if (strLine.isEmpty() == false) {
if (size() >= mQsize) {
Record t = tags.get(0);
t.Fields.clear();
tags.remove(0);
}
String bracketName=null;
String bracketValue=null;
do {
int start = 0;
int end = 0;
start = strLine.indexOf("<", bracket_start);
if (start<0) break;
end = strLine.indexOf("/>", start);
if (end<0) break;
String tmp = strLine.substring(start+1, end);
bracket_start = end;
start = 0;
end = tmp.indexOf(" ", start);
if (end<0) continue;
bracketName = tmp.substring(start, end);
bracketValue = tmp.substring(end+1, bracket_start-1);
} while (bracket_start>=0);
if (bracketValue!=null) {
String org = bracketValue;
Record t = new Record();
t.name = bracketName;
int index=0;
while (index < org.length()) {
Field f = new Field();
index = getField(org, index, f);
addField(t,f);
}
addRecord(t);
}
}
}
首先,需要创建 MessageManager 的对象:
MessageManager msgManager = new MessageManager();
然后通过 pushMessage(..) 填充缓冲区:
msgManager.pushMessage(strMsg);
根据需求,可以调用 popMessage(..):
record = msgManager.popMessage();
如果调用了 popMessage,最终可以使用返回的记录获取想要的字段:
field = msgManager.getField(record,index);
如果想要初始化缓冲区,可以调用 clear():
msgManager.clear();
以下是使用 MessageManager 的一个示例:
public static void main(String[] args) {
int buffsize = 6;
MessageManager.Record record = null;
MessageManager.Field field = null;
String strMsg1 = "";
String strMsg2 = "";
String strMsg3 = "";
String strMsg4 = "";
String strMsg5 = "";
String strMsg6 = "";
String strMsg7 = "";
MessageManager msgManager = new MessageManager();
msgManager.clear();
System.out.println("Add the buffer by strMsg1,strMsg2,...,strMsg5, buffer size:" + buffsize);
msgManager.setQsize(buffsize);
msgManager.pushMessage(strMsg1);
msgManager.pushMessage(strMsg2);
msgManager.pushMessage(strMsg3);
msgManager.pushMessage(strMsg4);
msgManager.pushMessage(strMsg5);
msgManager.pushMessage(strMsg6);
msgManager.pushMessage(strMsg7);
System.out.print("Print buffer--------------------------------------");
for (int i = 0; i < msgManager.size(); i++) {
record = msgManager.getRecord(i);
System.out.print("\n" + record.name + ":");
for (int j = 0; j < record.size(); j++) {
field = msgManager.getField(record, j);
if (field != null)
System.out.print("(" + field.name + ")" + field.value);
}
}
System.out.print("\nPop message-------------------------------------");
record = msgManager.popMessage();
System.out.print("\n" + record.name + ":");
for (int k = 0; k < record.size(); k++) {
field = msgManager.getField(record, k);
if (field != null)
System.out.print("(" + field.name + ")" + field.value);
}
System.out.print("\nbuffer after pop-------------------------------");
for (int i = 0; i < msgManager.size(); i++) {
record = msgManager.getRecord(i);
System.out.print("\n" + record.name + ":");
for (int j = 0; j < record.size(); j++) {
field = msgManager.getField(record, j);
if (field != null)
System.out.print("(" + field.name + ")" + field.value);
}
}
System.out.print("\nFind MsgId5 and it's field3---------------------");
record = msgManager.getRecord("MsgId5");
if (record != null) {
System.out.print("\n" + record.name + ":");
field = msgManager.getField(record, "field3");
} else {
System.out.println("\ncannot find record..");
field = null;
}
if (field != null)
System.out.print("(" + field.name + ")" + field.value);
else
System.out.println("\ncannot find field..");
msgManager.deleteMessage("MsgId6");
System.out.print("\nbuffer after Delete MsgId6 Message-------------");
for (int i = 0; i < msgManager.size(); i++) {
record = msgManager.getRecord(i);
System.out.print("\n" + record.name + ":");
for (int j = 0; j < record.size(); j++) {
field = msgManager.getField(record, j);
if (field != null)
System.out.print("(" + field.name + ")" + field.value);
}
}
}
可以按照以下指令编译并运行: