0

デバイスから常にデータを読み取る Java Modbus/TCP アプリケーションがあります。

これは 99.9% の時間正常に動作していますが、週末に動作した後、数秒間、Read Multiple Holding Registers 関数の偽の値を取得する奇妙なモードに入る可能性があります。

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;
}

return 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;
    

ストリームの読み取りで、保護されていない何かが足りないのかもしれません。

4

1 に答える 1

0
  1. null何かがうまくいかなかったり、理解できないことが起こったときに、ただ戻ってくるだけでは十分ではありません。そうすれば、接続を開いたままにして、次のバイトが新しいメッセージの始まりであると信じる理由がない非同期状態のままにします。したがって、それ以降、理解できないがらくたを読むことになります。接続を閉じて、再度開く必要があります。または、残りのプロトコルを実装します。

  2. ストリームから読み取った 10 ポイントのうち 9 ポイントで、ストリームの終わりをチェックしていません。

  3. もよく見てくださいDataInputStream。それは、あなたがすでに困難な方法で行っているすべてのことをすでに行っています。特にreadShort()と に注意してくださいreadFully()

于 2015-06-26T07:51:29.390 に答える