在将数据报转换为Java中的字节数组之后解析它

时间:2012-05-27 12:49:27

标签: java parsing udp bytearray

我正在尝试解析我将在套接字上收到的DatagramPacket。我知道我将收到的数据包的格式,这是一个DHCPREQUEST数据包,但我不认为这真的很重要。为简单起见,我们只考虑前六个字段:

第一个字段是“操作码”,即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中的字节数组有类似的方法吗?

或者我在某种程度上为自己制造困难?

4 个答案:

答案 0 :(得分:4)

将字节数组包装在ByteArrayOutputStream中;将DataInputStream包装起来;然后使用DataInputStream的方法。

答案 1 :(得分:3)

最简单的方法是使用实​​用方法Arrays.copyOfRange

答案 2 :(得分:2)

你要做的就是给自己编写一些辅助方法,从数据包中提取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规范要求的。

答案 3 :(得分:2)

我有点迟到了,但是有一个ByteBuffer类:

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