Parse DatagramPacket after converting it to byte array in Java

I am trying to parse the DatagramPacket that I will get on the socket. I know the format of the packet that I will receive, which is the DHCPREQUEST packet, but I do not think it really matters. For simplicity, we consider only the first six fields:

The first field is the "opcode", which is 1 byte.
The second field is the “equipment type”, which is 1 byte.
Thirdly, "hardware address length", 1 byte.
Fourth, hop, 1 byte.
Fifth, "transaction id xid", 4 bytes.
Sixth, "seconds", 2 bytes.

After receiving the packet, my approach is to convert it to an array of bytes.

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

At this point, the packet is stored in the buf byte array as a series of bytes. Since I know what the structure of this byte sequence is, how can I parse it? Single-byte fields are simple enough, but what about multi-bit fields? For example, how can I extract bytes 4 through 7 and store them in a variable called xid ?

I could manually put each byte in an array:

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

But this is just tedious and impractical for fields hundreds of bytes long. The String class can parse substrings based on offset and length; is there a similar method for byte arrays in java?

Or am I somehow complicating myself for myself?

+4
source share
4 answers

The cleanest way to do something like this is probably to use the Arrays.copyOfRange utility Arrays.copyOfRange .

+3
source

Wrap an array of bytes in a ByteArrayOutputStream; wrap a DataInputStream around this; then use the DataInputStream methods.

+4
source

What do you do, write yourself some helper methods to extract 2 bytes, 4 bytes, etc. from the packet. values, reading bytes and assembling them in Java short , int or any other values.

for instance

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

Then you use these helper methods as often as you need. (If you want to be a fantasy, you may have methods to update the attribute that contains the current position, so you don't need to pass the offset argument.)


Alternatively, if you weren’t bothered with the overhead, you can wrap the byte array in ByteArrayInputStream and DataInputStream and use the latest API to read bytes, shorts, int, etc. IIRC, DataInputStream assumes the numbers are represented in the stream in the "network byte order" ... which almost certainly matches the DHCP specifications.

+2
source

I'm a little late for this, but there is a ByteBuffer class:

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

Or if you only need one field:

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

Source: https://habr.com/ru/post/1414591/


All Articles