views:

103

answers:

2

Hi all,

I'm a C++ programmer and have a need to set up some UDP communications between a java android app and the C++ server running on a PC.

I have structure that I need to receive on the PC that consists of the following:

int
int
float

Unfortunately I'm totally at a loss as to how I can do this with Java.

I need to create a DatagramPacket but the constructor only takes a byte array. Now with C++ this would be an easy cast from a struct to a char*. However casting like this is not possible with Java.

I've create a simple class that has the above fields in it. That seems to be fine. My remaining issue is how to turn that into a byte array. Can anyone help a Java noob on this front?

Cheers!

Edit: I've created a function in the class that does the following

        public byte[] GetBytes() throws IOException
        {
            ByteArrayOutputStream   byteOut = new ByteArrayOutputStream();
            DataOutputStream        dataOut = new DataOutputStream( byteOut ); 
            dataOut.writeInt( Integer.reverseBytes( int1) );
            dataOut.writeInt( Integer.reverseBytes( int2 ) );
            dataOut.writeFloat( float1 );

            return byteOut.toByteArray();
        }

Is there a better way to do this?

I'd rather not use the google protocol buffer mentioned in Steve's answer because, while its interesting, it would require too many changes to other platform implementations that I'd really rather not do.

+6  A: 

You can use Google protocol buffers as a language-independent way to serialize structures for transmission and receipt. Both Java and C++ are available out of the box, and Jon Skeet has written a production-ready C# implementation.

I see a couple of examples of Protobuf in use on Android, including this.

Steve Townsend
+1  A: 

Another, maybe simpler approach comes from Javolution.struct: http://javolution.org/target/site/apidocs/javolution/io/Struct.html

 public static class Student extends Struct {
     public final Enum32<Gender>       gender = new Enum32<Gender>(Gender.values());
     public final UTF8String           name   = new UTF8String(64);
     public final Date                 birth  = inner(new Date());
     public final Float32[]            grades = array(new Float32[10]);
     public final Reference32<Student> next   =  new Reference32<Student>();
 }
class UDPMessage extends Struct {
      Student student = inner(new Student());
      ...
 }
 ...
 public void run() {
     byte[] bytes = new byte[1024];
     DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
     UDPMessage message = new UDPMessage();
     message.setByteBuffer(ByteBuffer.wrap(bytes), 0);
     // packet and message are now two different views of the same data.
     while (isListening) {
         multicastSocket.receive(packet);
         int xxx = message.xxx.get();
         ... // Process message fields directly.
     }
 }

Quite ugly piece of code, but still prettier than dealing directly with JNI buffers or already-mentioned Google protocol buffers.

iirekm