質問
CサーバーからJavaクライアントに16進メッセージを渡そうとしています。 コミュニケーションは機能します。しかし、Javaクライアントで取得した16進値には、「ff」が追加されているようです。なぜこれが起こっているのですか?
C側では、送信したいバイトを(16進数で)出力すると、問題ないように見えます。
以下のコードをご覧ください:
Cサーバー: ジェネラコディセタグプレ
Javaクライアント: ジェネラコディセタグプレ
OutPut: lenの値= -36 buffer [5]= 0 buffer [6]= 0xfffffffdc
更新
これが私のwireshark出力です(これはCサーバーがJavaクライアントにプッシュするものです):
行5の「00dc」はdatalen= 220に対応し、Javaクライアントのlenにそのまま保存する必要があることに注意してください。したがって、Javaクライアントには明らかにエラーがあります。皆さんがおっしゃったように、私はInteger.toHexString(((int)buffer [index])&0xFF)を使用して印刷できます。しかし、正しい16進値でバイト配列を格納する必要があります。助けてください ジェネラコディセタグプレ
解決
このような状況での最初のステップは、「ネットワーク経由」で何が送信されているかを確認することです。可能であれば、 wireshark または
しかし、その見た目から、署名された/署名されていない衝突が起こっていることに同意します。
この出力がある場合は、「誰が」障害を起こしているかを判断するのに役立ちます。
更新:
前述のように、マスクを解除して下位8ビットのみを使用する必要があります。これは、次の方法で実行できます。 ジェネラコディセタグプレ
これをコードに導入するには、2つの方法があります。1つは、バイトごとに呼び出す単純な静的関数です。例: ジェネラコディセタグプレ
もう1つは、DataInputStream.read()のラッパー関数で、バイトをバッファーに読み取り、すべてをマスクします。次のようになります: ジェネラコディセタグプレ
最初の方法を選択した場合は、使用する任意のbuffer []値でmask()を呼び出す必要があります。だから ジェネラコディセタグプレ
なります ジェネラコディセタグプレ
2番目の方法を選択した場合は、バッファをバイト型の配列からintに変更します。 ジェネラコディセタグプレ
whileループを次のように更新できます: ジェネラコディセタグプレ
しかし、それは言われています...
これらのいずれよりも優れたオプションは、 DataInputStreamのreadUnsignedByteメソッド。
自分で一度に40バイトをストリームから引き出す必要がありますが、少しいじるよりも、何をしていたかがはるかに明確になります。私の意見では、これが好ましいアプローチです。
他のヒント
Javaのバイトは署名されています。したがって、最上位ビットが設定されている各値は負の値です。Integer.toHexStringを呼び出すときに発生する整数に変換されると、符号が拡張されます。したがって、10000000bの場合、0x80ではなく11111111111111111111111110000000bまたは0xFFFFFF80になります。それは32ビットで同じ負の値だからです。やっている ジェネラコディセタグプレ
修正する必要があります。
BTW、Javaには符号なしの型はありません。
Integer.toHexString(buffer[index] & 0xFF )
で問題が修正されます。
符号ビットの伝播のように聞こえます。lenおよびその他のJAVA変数は、署名されるべきではないときに署名されているように見えます。