C Structure for Java Objects over UDP

I am new to Java and C programming and need some help. Therefore, I have a C application that sends structures via UDP:

#include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <string.h> int main(int argc, char**argv) { int sockfd,n; struct sockaddr_in servaddr,cliaddr; struct dataType { char name[4]; unsigned short did; unsigned short sid; unsigned short type:4,pri:2,cb:2,flags:8; unsigned char pblock; unsigned char tblock; unsigned short mess; unsigned int window:24; }; struct dataType sample_header; strcpy(sample_header.name,"TEST"); sample_header.did=23; sample_header.sid_id=1; sample_header.type=1; sample_header.pri=01; sample_header.cb=1; sample_header.flags=18; sample_header.pblock=10; sample_header.tblock=20; sample_header.mess3; sample_header.window=123890; sockfd=socket(AF_INET,SOCK_DGRAM,0); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr=inet_addr(argv[1]); servaddr.sin_port=htons(6120); sendto(sockfd, (char *)&sample_header, (sizeof(struct dataType)),0,(struct sockaddr *)&servaddr,sizeof(servaddr)); } 

Now I need to be able to receive this data through UDP in Java and populate the object with these values. I can get the first row (name), but I don’t know how to get the remaining elements.

  import java.net.DatagramPacket; import java.net.DatagramSocket; import java.io.*; import java.net.*; import java.awt.*; import java.nio.*; public class UDPReceive { public static void main(String args[]) { try { int port = 6120; DatagramSocket dsocket = new DatagramSocket(port); byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); while (true) { dsocket.receive(packet); byte[] data = packet.getData(); String msg1 = new String(data, 0, 5); System.out.println("Here is SOME :" + msg1); packet.setLength(buffer.length); } } catch (Exception e) { System.err.println(e); } } } 

I looked at the Google protocol buffers, but obviously this requires changes on both sides. I should also be able to end up sending this data from the Java object to UDP and return to the C structure.

Thank you very much.

+4
source share
4 answers

You should not write C structures to the network at all due to content and bit issues. Instead, you want to go through a sorting and encoding process in which you record each structural memory in a portable network encoding format. The other side reads in a portable network format and saves it, but it is necessary.

This is how all standard RFCish Internet protocols work. They determine the order, encoding, entity, and other semantics of all fields. Yes, they sometimes arrange it so that a carefully designed structure can be superimposed in a network buffer, but even then they often have to execute htons () or friends in buffers to get them in the correct form.

I recommend using this approach.

Reading your structure, it is not laid out in a way that facilitates sending directly to the network. It would seem very likely that there are holes in the structure, for example, which would be very difficult for other systems to correctly decode.

+3
source

One way is to create java.io.ByteArrayInputStream data from byte [] and wrap it in a DataInputStream, which offers methods for reading other primitive types.

You might want to chain integers in network order. On the C side, you can use ntohl, htonl, ntohs, htons, etc. If you use bit fields, you will have to translate them manually on the Java side.

+1
source

First you need to serialize the data first and then decode them in java.

 void write_dataType( char* buff, dataType* data ) { sprintf( buff, "%s\n%d\n", name, data.did ); } 

You could, of course, use real RPC technology .

0
source

Several people have already provided good answers to this question. Just sending a c-structure via a UDP datagram can cause time problems. Serialization using XML or JSON will give you much greater flexibility and independence of the sender / receiver.

That was said ... Java has a trivial way to do what you want. Just wrap the byte array from the incoming UDP datagram using ByteBuffer. ByteBuffer has methods for getting bytes, characters (Java characters, as in Unicode characters), shorts, ints and longs from ByteBuffer.

The code is very simple. However, as others have pointed out ... This is still a bad idea. Use JSON or XML, if possible. Save JSON or XML in UTF-8 format in a UDP datagram before sending. On the receiving side, convert UTF-8 back to a Java string (the new String () in the byte array containing UTF-8 works correctly) and then unmarshall JSON or XML.

0
source

All Articles