2017-07-18 122 views
-1

问题: 我需要从具有固定的数据包格式定义的电子设备实现网络输入读取器。它有一个页眉,页脚和数据体。数据包中的字段是按位定义的。Java自定义序列化和反序列化的位大小定义

实施例: 字段sequence_number变量是编号为8至31中的比特和ack_status是位32如何创建一个自定义序列函数,这样我可以Java对象转换为和从一个字节[]读从一个数据包?

在32位包

StartOfPacketHeader 4位

CommandCode 4位

的SequenceNumber 23bits

AckStatus 1位

如何使一个Java包装类此对象使用byte []构造函数和toBytes()方法。

使用Serializable接口不能控制单个数据大小。数据大小可能是奇数值,如3位或18位变量。我无法用位来指定变量的长度。

我迄今所做的:

源实际发送的无符号整数,这意味着Java的整型不能处理它的整个范围。我需要定义所有数据类型,以处理所有情况。我已经使用BitSet类来执行字节[]长转换,但它只是太繁琐和混乱,因为bitset默认将位顺序颠倒为Little Endian。

摘要:

如何转换到我的对象从我从网络上,反之亦然每个字段的用户自定义的最有效的方式读取的字节[]?

回答

0

您为此使用DataInputStreamDataOutputStream,为了提高效率,分别使用BufferedInputStreamBufferedOutputStream。您必须自己编写位字段,但这些类按网络字节顺序提供所有Java基元。

为您发布的数据包,你需要的东西是这样的:

class Packet 
{ 
    private byte header; 
    private byte commandCode; 
    private int  sequenceNumber; 
    private boolean ackStatus; 

    void write(DataOutput out) throws IOException 
    { 
     int wirePacket = header|(commandCode << 4)|(sequenceNumber << 8); 
     if (ackStatus) 
     { 
      wirePacket |= 0x80000000; 
     } 
     out.writeInt(wirePacket); 
    } 

    static Packet read(DataInput in) throws IOException 
    { 
     Packet packet = new Packet(); 
     int wirePacket = in.readInt(); 
     packet.header = (byte)(wirePacket & 0x0f); 
     packet.commandCode = (byte)((wirePacket >>> 4) & 0x0f); 
     packet.sequenceNumber = (wirePacket >>> 8) & 0x7FFFFF; 
     packet.ackStatus = (wirePacket & 0x80000000) != 0; 
     return packet; 
    } 
    // getters and setters. The setters must ensure that the values don't go out of range. 
} 
+0

你能举一个例子吗? –

+0

为什么?你不能读Javadoc吗? – EJP

+0

我需要逻辑?我已经知道如何使用他们 –