在Java中将其转换为一个字节数组后解析的DatagramPacket(Parse a Datagr

2019-07-29 14:35发布

我试图解析,我会收到在插座的DatagramPacket。 我知道我包将接受,这是一个DHCP请求报文的格式,但我不认为这真的很重要。 为简单起见,我们只考虑前六个领域:

第一字段是“操作码”,这是1个字节。
第二字段是“硬件类型”,这是1个字节。
第三,“硬件地址长度”,1个字节。
四, “跳跃”,1个字节。
第五, “事务标识符XID”,4个字节。
第六, “秒”,2个字节。

我收到报文后,我的做法是将其转换为一个字节数组。

DatagramPacket request = new DatagramPacket(new byte[1024], 1024);
socket.receive(request);
byte[] buf = request.getData();

在这一点上,数据包被存储在字节数组中buf作为一系列字节组成。 因为我知道这个字节序列的结构是什么,我该怎么分析它? 一个字节的领域是很简单的,但如何对多比特字段? 例如,我怎么能提取字节4到7,并将其存储在一个变量命名xid

我可以手动把每个字节到一个数组:

byte[] xid = new byte[4];
xid[0] = buf[4];
xid[1] = buf[5];
xid[2] = buf[6];
xid[3] = buf[7];

但是,这只是单调乏味,和不切实际的是数百个字节长度的领域。 String类可以解析子串给出的偏移量和长度; 有没有在Java字节数组类似的方法?

还是我不知怎么做我自己的事难吗?

Answer 1:

最干净的方式做这样的事情可能是使用的实用方法Arrays.copyOfRange



Answer 2:

包裹在一个ByteArrayOutputStream字节阵列; 环绕该一个DataInputStream; 然后使用DataInputStream类的方法。



Answer 3:

你要做的就是自己写的一些辅助的方法来从包中提取值2字节,4字节,等等,读字节并将其组装成Java shortint任何值或。

例如

    public short getShort(byte[] buffer, int offset) {
        return (short) ((buffer[offset] << 8) | buffer[offset + 1]);
    }

然后,你经常你需要使用这些辅助方法。 (如果你想成为幻想,你可以有两种方式更新保存当前位置的属性,让你不必传递一个offset参数)。


另外,如果你没有被开销担心,你可以换的字节数组ByteArrayInputStreamDataInputStream ,并使用后者的API来读取的字节,短裤,整数,等等。 IIRC, DataInputStream假定的数字在“网络字节顺序” ......这几乎肯定是什么DHCP规范任务流中表示。



Answer 4:

我有点晚了这一点,但有一个字节缓冲区类:

ByteBuffer b = ByteBuffer.wrap(request.getData());

byte opcode = b.get();
byte hwtype = b.get();
byte hw_addr_len = b.get();
byte hops = b.get();
int xid = b.getInt();
short seconds = b.getShort();

或者,如果你只需要一个单场:

ByteBuffer b = ByteBuffer.wrap(request.getData());
int xid = b.getInt(4);


文章来源: Parse a DatagramPacket after converting it to a byte array in Java