We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Unpacking UDP Packet to ints/chars/bytes/floats
Page Index Toggle Pages: 1
Unpacking UDP Packet to ints/chars/bytes/floats (Read 2357 times)
Unpacking UDP Packet to ints/chars/bytes/floats
Jun 20th, 2009, 12:48pm
 
Hello.  Smiley

(I cannot post links yet- Sorry)

I have a racing simulator (some call it a game...) that outputs gauge info such as speed and RPM over UDP.
(For detailed information on the data, go to lfsforum.net and search for "outgauge scawen". The 4th post down is called "Outgauge -  now available in T6".)

Using the Processing UDP library by Stephane Cousot found on the Processing.org libraries page I am able to receive the packet, print it to serial and see the pieces that are contained in char data types.
The problem lies with the others. I can't find a newbie compatible way to unpack the data into variables of the corresponding types.

Go to
img526[dot]imageshack.us[slash]img526/7485/processingudp.gif
for a screenshot showing my sketch and the packet I'm receiving.

Could someone help me out?  Sad
Re: Unpacking UDP Packet to ints/chars/bytes/floats
Reply #1 - Jun 20th, 2009, 2:34pm
 
I'm not sure I fully understand what you're printing to the output window.  Is that the raw data you receive over UDP  TBH what's being printed out would suggest to me a problem at the sending end rather than receiving end of the message - unless you've parsed it in some way

It might help to post some code Wink
Re: Unpacking UDP Packet to ints/chars/bytes/floats
Reply #2 - Jun 20th, 2009, 11:09pm
 
How are you sending the data just as a string Always
You may need to convert it to bytes.

I had made a 3d chat sketch that allowed people to chat with each other as long as they're on the same network.

In order to get everything across, I had to send it as bytes.
I just posted the example on another thread.

You can download my source files here:
http://computerarts.ca/_files/processing/3DChat.zip

What might interest you is the "conversion" tab.


Hope it helps in some way.
Cheers
Steven
Re: Unpacking UDP Packet to ints/chars/bytes/floats
Reply #3 - Jun 21st, 2009, 5:35pm
 
Thanks- Sorry it took so long...I was expecting an email notification.

The data is sent in a UDP packet comprised of different values in different data types. (RPM as a float, for example.)
There is an example VB6 program a few posts lower in the lfsforum thread. Also, here is one in C++ that outputs the data to LPT (Parallel port):
[tinyurl com] /klakh2
As a final result, I need to send the data over serial to the Arduino IDE, which is very similar to Processing. (I don't know if they're related at all.)

Steven: If I understand your program correctly, it converts to a byte by reading each character in a string until i == bytelength, and then outputting the byte. Correct?
The link at the top of your program is also interesting.
Re: Unpacking UDP Packet to ints/chars/bytes/floats
Reply #4 - Aug 20th, 2009, 3:05pm
 
Hello,

I was trying to do something similar, this has been driving me nuts and I finally figured it out. Since this seems to be the only thread on the subject, I thought I'd share my solution here.

I have a Python program that does some very math-ish manipulations of maps. It uses the Python struct module to pack some visualization information into UDP packets and send it to a Processing sketch once in a while so I can watch its progress in a more intuitive form.

At first I was trying to use DataInputStreams, which have methods for reading different data types, using code like this:

Code:
byte b;
InputStream in = new ByteArrayInputStream(data);
DataInputStream din = new DataInputStream(in);
b = din.readByte();


Check the Java documentation if you want to go this route.

But it turns out that Java always uses network byte order (big-endian) for byte streams, and the byte order in my messages was little-endian (they were just packed C structures from an Intel machine) so I started looking at ByteBuffers, which allow you to reverse the byte order before reading from them. However, this was not really the 'right' way to do things since network packets should by convention be in big-endian order. So I fixed my network packets, but still decided to stick with ByteBuffers for the simple interface, and the fact that a buffer seems to be a better fit than a stream for what we're doing.

(Side note for people doing this with Python: if your packets are being generated by the Python struct module, you can add a character '!' to the beginning of the format string to force the contents into network byte order.)

OK I know this is not 'newbie friendly' as the original poster put it, so simplified version is as follows: the order of the bytes in your UDP message is relevant. However, if the message is coming from a standards-compliant application, it will agree with Java/Processing on that order.

On to the example:

Code:
import java.nio.ByteBuffer;

void receive( byte[] data, String ip, int port ) throws IOException {
 // Java/Processing defaults to read in network byte order.
 // Python will send in machine unless you specify in struct.pack().
 // Both ByteBuffers and DataInputStreams are good for unpacking data.
 int row, col, t;
 float x, y, z;
 byte b;
 ByteBuffer bb = ByteBuffer.wrap(data);
 b = bb.get();
 if (b == (byte)'T') {
   while (bb.hasRemaining()) {
     row = bb.get() & 0xFF;
     col = bb.get() & 0xFF;
     t = (int) (bb.get() & 0xFF);
     if (row < 100 && col < 100) ttimes[row][col] += t;
   }
 } else if (b == (byte)'P') {
   while (bb.hasRemaining()) {
     row = bb.get() & 0xFF;
     col = bb.get() & 0xFF;
     x = bb.getFloat();
     y = bb.getFloat();
     z = bb.getFloat();
     if (row < 100 && col < 100) {
       targetMesh[row][col].x = x;
       targetMesh[row][col].z = y;
       targetMesh[row][col].y = z;
     }
   }
 }
}


The &0xFF in my code is to get unsigned values out of the bytes, since Java only does signed values. Again, I know this is not terribly friendly to a beginner, but when you start manipulating byte-level representations of numbers things get slightly messy. But there's lots of info online to figure it all out.

Hope this helps!
Page Index Toggle Pages: 1