0

I'm new to Java and writing a program with its own network protocol via UDP/TCP. There's such a packet in C:

struct test_package {
    u32 cmd;
    u32 args;
    u32 flags;
};

Taking UDP as example, what I get from the DatagramPacket is byte data[]. How can I convert it to a package struct?

If in C, it's just (struct test_package *)data if there's no alignment restriction.

Thanks

1
  • You need to be aware that putting C structs directly onto the wire is very poor engineering. It introduces dependencies on the compiler, compiler version, surrounding #pragmas in effect, compiler options used when compiling that day, ... Not recommended. You have to define a network byte protocol and write whatever you have to write in your programming language to implement that correctly. The supposed inefficiencies of Java when doing that correctly are not comparable with the apparent efficiency of C when doing it wrong. Commented Jul 25, 2012 at 7:03

2 Answers 2

1

Say you have a class:

public class TestPackage implements Serializable
{
   long cmd;
   long args;
   long flags;
}

You can store that in a DatagramPacket as byte[] by serializing it. Then on the other end, you can take the byte[] and deserialize it back to the exact instance of TestPackage.

(Here's what the serialize/deserialize could look like)

public static byte[] serialize(Object object) {
   ByteArrayOutputStream out = new ByteArrayOutputStream();
   ObjectOutputStream oos = new ObjectOutputStream(out);
   oos.writeObject(object);
   return out.toByteArray();
}

public static Object deserialize(byte[] datagramData) {
   ByteArrayInputStream in = new ByteArrayInputStream(datagramData);
   ObjectInputStream ois = new ObjectInputStream(in);
   return ois.readObject();
}
Sign up to request clarification or add additional context in comments.

3 Comments

This will work, but it assumes that both ends are running a Java-based client.
It looks like a generic way to serialize/deserialize. But does it guarantee the byte [] data layout is the same as struct test_package?
@user1550330 No, the layout isn't going to be the same, like casablanca says, it assumes the other end is also Java and that you are passing Classes back and forth.
0

Java does not provide direct memory access, so you cannot cast it to a structure as you can in C. You have to parse the byte array yourself, for example:

byte data[] = ...;
DataInput input = new DataInputStream(new ByteArrayInputStream(data));

int cmd = input.readInt();
int args = input.readInt();
int flags = input.readInt();

2 Comments

It looks like I have to implement such code for every kind of packages. It looks a little redundant and I have to do that. And I'm not sure how it keep efficiency to have such memory copies.
@user1550330: Yes, it is somewhat redundant but Java is really meant for object-oriented code rather than low-level data like this. If you are also concerned about efficiency, maybe Java isn't the right solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.