How to get data out of network packet data in Java

c, java, networking, packet, udp

Solution

Read your packet into a byte array, and then extract the bits and bytes you want from that.

Here's a sample, sans exception handling:

DatagramSocket s = new DatagramSocket(port);
DatagramPacket p;
byte buffer[] = new byte[4096];

while (true) {
    p = new DatagramPacket(buffer, buffer.length);
    s.receive(p);

    // your packet is now in buffer[];
    int version = buffer[0] << 24 + buffer[1] << 16 + buffer[2] < 8 + buffer[3];
    byte[] serverId = new byte[20];
    System.arraycopy(buffer, 4, serverId, 0, 20);

     // and process the rest
}

In practise you'll probably end up with helper functions to extract data fields in network order from the byte array, or as Tom points out in the comments, you can use a `ByteArrayInputStream()`, from which you can construct a `DataInputStream()` which has methods to read structured data from the stream:

...

while (true) {
    p = new DatagramPacket(buffer, buffer.length);
    s.receive(p);

    ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
    DataInput di = new DataInputStream(bais);

    int version = di.readInt();
    byte[] serverId = new byte[20];
    di.readFully(serverId);
    ...
}

Problem

In C if you have a certain type of packet, what you generally do is define some struct and cast the char * into a pointer to the struct. After this you have direct programmatic access to all data fields in the network packet. Like so : ``` struct rdp_header { int version; char serverId[20]; }; ``` When you get a network packet you can do the following quickly : ``` char * packet; // receive packet rdp_header * pckt = (rdp_header * packet); printf("Servername : %20.20s\n", pckt.serverId); ``` This technique works really great for UDP based protocols, and allows for very quick and very efficient packet parsing and sending using very little code, and trivial error handling (just check the length of the packet). Is there an equivalent, just as quick way in java to do the same ? Or are you forced to use stream based techniques ?

Original source