2015-06-26 2 views
0

У меня есть приложение Java Modbus/TCP, которое постоянно считывает данные с устройства.Socket получить входной поток, считывая неправильные значения несколько раз

Это нормально работает 99,9%, но после выходных дней он может войти в странный режим, в котором в течение нескольких секунд я получаю поддельные значения моих функций Read Multiple Holding Registers.

Я проверил с помощью приложения Modscan, а поддельные значения отображаются на клиентском сайте, что означает, что серверное устройство отвечает правильно.

Ответ, который я могу получить, представляет собой массив байтов, заполненный 0, 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; 
} 

Возвращение нуль обрабатывается вне функции, как неправильное исключение.

У меня было добавить 2 защиты:

  • чтения() метод возвращает -1 после EOF, поэтому я добавляю:

    int res=is.read(); 
        if(res<0){ 
         //Modbus Stream Reading is returning -1 
         return null; 
        } 
    
  • Возврат нуль для неподдерживаемых методов Modbus/TCP:

    default:///unsupported Modbus Methods 
         return null; 
    

Возможно, я м что-то большее в потоковом чтении, к которому у меня нет защиты.

ответ

0
  1. Это не достаточно, чтобы просто вернуть null когда что-то идет не так, или вы получите то, что вы не понимаете. Таким образом, вы просто оставляете соединение открытым и в несинхронизированном состоянии, где у вас нет причин полагать, что следующий байт является началом нового сообщения. Итак, с тех пор вы прочтете непонятный мусор. Вам нужно закрыть соединение и снова открыть его. Или выполните остальные протоколы.

  2. Вы не проверяете конец потока в девяти из десяти пунктов, которые вы читаете на нем.

  3. Вы также должны хорошо посмотреть DataInputStream. Он уже делает все, что вы уже делаете. Особенно примечательны примечания readShort() и readFully().

Смежные вопросы