1

ソケットから読み取ったデータがあり、次の形式であることがわかっています。

[2バイト][8バイト][2バイト]=12バイト

別々に読みたいこと。値は16進数です。私は実際にそのデータをPHPでキャプチャしてファイルに保存し、od(unix)を使用して適切に表示できます。

$ od -h myFile
$ 0000000 02eb 02fe fe02 fefe 02fe 02fe 000a
$ 0000015 

つまり、最後にCRとLFがあり、結果は14バイトになります。ソケットからJava読み取りでこれらの値を取得するにはどうすればよいですか?たとえば、その「02eb」(2バイト)を取得して10進値に変換するにはどうすればよいですか?

私はすでにソケットから読んでいます、私が試した最後のことは:

mMessage = mBRin.readLine();
byte[] bytes = mMessage.trim().getBytes()

しかし、それは私に配列の18バイトを与えます。

それが役に立ったら、PHPでその最初の部分を取得するために私はしました:

$input = socket_read($value,13,PHP_BINARY_READ);
$trim_input = trim($input);
$float_head = hexdec(bin2hex(substr($input,0,2)));

私はこれを理解していないと思います、それが答えかもしれません

4

2 に答える 2

2

ソケットから読み取ったデータがあり、次の形式であることがわかっています。

[2バイト][8バイト][2バイト]=12バイト

ソケットからバイトを読み取るコードがすでにある場合は、ByteBufferを使用して、バイトをshort、int、longなどの値に変換できます。

Socket s = .....;

InputStream in = s.getInputStream();
byte [] buf = new byte[12];

// read 12 bytes from socket into bytes
in.read(buf);

ByteBuffer bb = ByteBuffer.allocate(buf.length);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(buf);
bb.flip();
short short1 = bb.getShort();
long long1 = bb.getLong();
short short2 = bb.getShort();

バイトバッファをリトルエンディアンに設定するための呼び出しに注意してください。

odコマンドを実行すると、次のような出力が得られました(この出力は、システム上で作成したファイルから取得したものです)。od -hコマンドは、ファイルからバイトを読み取り、リトルエンディアンモードで2バイトのショートとしてまとめてから、ショート値を16進数で出力します。

$ od -h binary.dat 
0000000      02eb    02fe    fe02    fefe    02fe    02fe    000a        
0000015

ただし、-tx1を使用すると、ファイルに表示される実際の順序でバイトが表示されます。

$ od -tx1 binary.dat
$ 0000000    eb  02  fe  02  02  fe  fe  fe  fe  02  fe  02  0a
$ 0000015

これをファイルで実行すると、実際には14バイトではなく13バイトであり、CRLFではなく単一のLFで終了していることがわかります。あなたが見た「余分な」バイトはod-hからの「存在」でしたが、実際にはファイルに存在しません。

とにかく、最初のバイトは値235(16進数のEB)です。2番目のバイトは2です。問題は-その最初の短い欲求の正しい値は何ですか。ソケットプロトコルに従って、データがリトルエンディアンモードでシリアル化される場合、shortに連結された2バイトの値は02EB hexまたは747です。ソケットプロトコルがビッグエンディアンを使用する場合、値はEB02hexまたは60162です。

ByteBufferアプローチは柔軟性を提供し、ビッグエンディアンまたはリトルエンディアンのいずれかで読み取り/書き込みを行うことができます。また、ソケットからのデータの読み取りを(バイト配列に)分離し、後でデータを数値に変換することもできます。これにより、さまざまなテストケースのバイト配列を作成し、解析コードが期待どおりに機能することを確認できるため、単体テストが容易になる場合があります。

sharadenduの回答のDataInputStreamアプローチも機能しますが、ソケットプロトコルがビッグエンディアンである場合に限ります。DataInputStreamはビッグエンディアンにハードコーディングされています。

于 2012-09-19T00:02:36.633 に答える
2
Socket socket = ......;
        DataInputStream dis = new DataInputStream(socket.getInputStream());
        short f1 = dis.readShort();
        long f2 = dis.readLong();
        sort f3 = dis.readShort();

値を 16 進数で出力するには、String.format("%x",f1); を使用します。それが役に立てば幸い ...

于 2012-09-18T21:06:14.530 に答える