我有一个Java Modbus / TCP应用程序,它不断地从设备读取数据。
这种情况正常工作99.9%,但经过一个周末工作后,它可能会进入一种奇怪的模式,在这种情况下,我会得到我的Read Multiple Holding Registers功能的伪值。
我已经使用Modscan应用程序进行了检查,并在客户端站点上显示虚假值,这意味着服务器设备正在正确回答。
我能得到的答案是一个字节数组,填充了0,1,1和其他随机值。
这是我的Modbus / TCP答案阅读:
private byte[] getModbusReply(){
byte[] reply = null;
int transactionId;
int protocol;
int tcpLen;
int id;
int replyCode;
int mbLen = 1;
try{
InputStream is = socket.getInputStream();
transactionId = (is.read()<<8)+is.read();
protocol = (is.read()<<8)+is.read();
tcpLen = (is.read()<<8)+is.read();
id = is.read();
replyCode = is.read();
if(replyCode>0x3F){
mbLen = 1;
}else{
switch(replyCode){
case 0x03:
case 0x04:
mbLen = is.read();
break;
case 0x10:
case 0x06:
mbLen = 4;
break;
default://unsupported Modbus Methods
return null;
}
}
reply = new byte[mbLen+1];
reply[0] = (byte)replyCode;
for(int i=1;i<reply.length;i++){
int res=is.read();
if(res<0){
//Modbus Stream Reading is returning -1
return null;
}
reply[i] = (byte)res;
}
}catch(Exception e){
e.printStackTrace();
return null;
}
return reply;
}
返回null在函数外部处理为错误的异常。
我添加了2项保护措施:
read()方法在EOF之后返回-1,所以我添加:
int res=is.read();
if(res<0){
//Modbus Stream Reading is returning -1
return null;
}
对不支持的Modbus / TCP方法返回null:
default:///unsupported Modbus Methods
return null;
也许我错过了一些我没有保护的流阅读。
答案 0 :(得分:0)
当出现问题或者你得到一些你不理解的东西时,只返回null
是不够的。这样你只需要保持连接打开并处于不同步的状态,你没有理由相信下一个字节是新消息的开头。所以,从那时起,你会读到无法理解的垃圾。您需要关闭连接并重新打开它。或者,实施协议的其余部分。
您不会在从中读取的十个点中的九个点检查流的结尾。
您还应该好好了解DataInputStream
。它已经完成了你已经做的所有事情。请特别注意readShort()
和readFully()
。