解析通过TCP套接字服务器接收的java二进制数据

解析通过TCP套接字服务器接收的java二进制数据,java,parsing,binary-data,serversocket,Java,Parsing,Binary Data,Serversocket,我有一个套接字服务器,它不断监听传入的请求。接收的数据将以二进制字节数组的形式出现。 数据格式是这样的。 2321902321221200AA 而1字节是数据开始 4位是版本 4位是数据返回类型 5字节是产品代码 2字节数据长度 问题是,如何解析数据和分离参数 提前谢谢 您可以通过 try { char [] cbuf = new char[16]; char databegin = cbuf[0]; char [] version = Arrays.copyOfRa

我有一个套接字服务器,它不断监听传入的请求。接收的数据将以二进制字节数组的形式出现。 数据格式是这样的。 2321902321221200AA

  • 1字节是数据开始
  • 4位是版本
  • 4位是数据返回类型
  • 5字节是产品代码
  • 2字节数据长度
问题是,如何解析数据和分离参数


提前谢谢

您可以通过
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);
}
然后通过应用掩码(主要是And、OR)解析字节

看看

希望这有帮助

byte[]data=receiveData();
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
int-dataBegin=data[0];//一旦字段是1字节,它就简单了! int version=data[1]&0x0F;//使用shift(>>>)和二进制“and”(&) int returnCode=//提取 (数据[1]>>>4)&0x0F;//小于一个字节 byte[]productCode=//复制数据的固定大小部分 使用硬代码将新字节[]{//放入单独的数组中 数据[2]、数据[3]、/(如此处所示)或System.arrayCopy 数据[4],数据[5],//以防字段占据相当大的空间 数据[6]};//许多字节。
int dataLength=//使用shift(尝试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;

我会得到一些包装读取器之王:

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框架。

如果使用,那么代码将如下所示

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

ByteArrayOutputStream没有回答问题,它只是移动了问题。