【问题标题】:Socket get input stream reading wrong values few times套接字获取输入流多次读取错误值
【发布时间】:2015-09-13 00:13:11
【问题描述】:

我有一个 Java Modbus/TCP 应用程序,它不断地从设备读取数据。

这在 99.9% 的情况下正常工作,但在一个周末工作后,它可能会进入一种奇怪的模式,在这几秒钟内,我的读取多个保持寄存器函数的值是假的。

我使用 Modscan 应用程序检查过,客户端站点上出现虚假值,这意味着服务器设备正在正确应答。

我能得到的答案是一个由 0、1 和其他随机值填充的 Byte 数组。

这是我的 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;
    

也许我在流式阅读中遗漏了更多我没有保护的东西。

【问题讨论】:

    标签: java sockets socket.io inputstream modbus-tcp


    【解决方案1】:
    1. 当出现问题或遇到不理解的内容时,仅返回 null 是不够的。这样,您只是使连接保持打开状态并处于非同步状态,您没有理由相信下一个字节是新消息的开始。因此,从那时起,您将阅读难以理解的垃圾。您需要关闭连接并重新打开它。或者,实现协议的其余部分。

    2. 您没有在从它读取的十个点中有九个检查流结束。

    3. 你也应该好好看看DataInputStream。它已经完成了你已经在艰难地做的所有事情。特别注意readShort() 和readFully()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-11
      • 1970-01-01
      • 2015-07-12
      • 1970-01-01
      • 2013-03-10
      • 2011-05-31
      • 2012-08-16
      • 1970-01-01
      相关资源
      最近更新 更多