受信リクエストをリッスンし続けるソケットサーバーがあります。受信したデータは、バイトのバイナリ配列の形式になります。データ形式はこんな感じ。 2321902321221200AA
- 1バイトはデータの始まりですが
- 4ビットはバージョン
- 4ビットはデータリターン型
- 5バイトは商品コード
- 2バイトのデータ長
問題は、データを解析してパラメーターを分離する方法です。
前もって感謝します!!
受信リクエストをリッスンし続けるソケットサーバーがあります。受信したデータは、バイトのバイナリ配列の形式になります。データ形式はこんな感じ。 2321902321221200AA
問題は、データを解析してパラメーターを分離する方法です。
前もって感謝します!!
java.io.DataInputStream を試してください:
DataInputStream dis = new DataInputStream(in);
byte b = dis.readByte();
int version = (b >> 4) & 0xF;
int returnType = b & 0xF;
byte[] productCode = new byte[5];
dis.readFully(productCode);
int len = dis.readShort() & 0xFFFF;
Javaバイナリブロックパーサーを使用すると、コードは次のようになります
class Parsed {
@Bin byte begin;
@Bin(type = BinType.BIT) int version;
@Bin(type = BinType.BIT) int returnType;
@Bin byte [] productCode;
@Bin(type = BinType.USHORT) int dataLength;
}
final Parsed parsed = JBBPParser.prepare("byte begin; bit:4 version; bit:4 returnType; byte [5] productCode; ushort dataLength;")
.parse(new byte[]{0x23,0x21,(byte)0x90,0x23,0x21,0x22,0x12,0x00,(byte)0xAA})
.mapTo(Parsed.class);
assertEquals(0x23, parsed.begin);
assertEquals(0x01, parsed.version);
assertEquals(0x02, parsed.returnType);
assertArrayEquals(new byte[]{(byte)0x90,0x23,0x21,0x22,0x12}, parsed.productCode);
assertEquals(0x00AA,parsed.dataLength);
try {
char [] cbuf = new char[16];
char databegin = cbuf[0];
char [] version = Arrays.copyOfRange(cbuf, 1, 6)
char [] product_typep = Arrays.copyOfRange(cbuf, 7, 12)
char []data_lendth = Arrays.copyOfRange(cbuf, 13, 15)
} catch(Error e){
System.out.println(e);
}
byte [] data = receiveData ();
int dataBegin = data [0]; // Once field is 1-byte, it is simple!
int version = data [1] & 0x0F; // Use shift (>>>) and binary "and" (&)
int returnCode = // to extract value of fields that are
(data [1] >>> 4) & 0x0F; // smaller than one byte
byte [] productCode = // Copy fixed-size portions of data
new byte [] { // into separate arrays using hardcode
data [2], data [3], // (as here), or System.arrayCopy
data [4], data [5], // in case field occupies quite
data [6]}; // a many bytes.
int dataLength = // Use shift (<<) binary or (|) to
(data [7] & 0xFF) | // Combine several bytes into one integer
((data [8] & 0xFF) << 8); // We assume little-endian encoding here
私はパッケージリーダーの王様を手に入れました:
class Record {
.....
Record static fromBytes(byte[] bytes) {
// here use ByteBuffer or DataInputStream to extract filds
......
}
}
Record readNextRecord(InputStream in) {
int len = in.read() && 0xFF;
byte[] data = new byte[len];
in.read(data);
return Record.fromBytes(data)
}
{
InputStream in = ....;
Record r readNextRecord(in);
process (r);
}
もちろん、エラー処理を追加する必要があります。一般に、信頼できるものを実行する必要がある場合は、Grizzly や Netty などの NIO フレームワークを使用することをお勧めします。