Gordon said:
Others have already pointed out how you can read the data, however
it's worth mentioning that if the server gets recompiled with a
different compiler, or moved to a different platform (with no changes
to the data types) it could break your client.
The real solution is to change the server so that it doesn't write the
data in a format that is quite so compiler and platform dependent.
Writing raw binary data directly from a C struct is lazy, fragile and
non-portable. And as you've already discovered, it makes it difficult
and error prone to write a client in a different language, that
doesn't use the same compiler, or that will run on a different
hardware platform.
/gordon
Hi,
Thank you all for your invaluable advice. To date, I have seemed to
try all the methods mentioned: Array, ByteBuffer, DataInputStream,
ByteArrayInputStream, intBitsToFloat(), etc. I had, ofcourse as Michael
Borgwardt so "brilliantly" pointed out, tried putting some values on the
server side and dumping them out on the client side (That is HOW I know
they are not the same!!!).
Flatform and hardware also are not the concern since I had tried
running the server on the very same intel machine as the client (just to
debug). Endianess is also out of question in this scenario.
This is how I do it:
// The data format from a C server.
// To make thing simple, I make all fiels float
typede struct {
float something;
float some_other_thing; ...
}
// class to convert data on the java end
public class StructureInputStream extends ByteArrayInputStream
{
static int curr = 0;
private DataInputStream dis = null;
public StructureInputStream(byte[] b)
{
super(b);
curr = 1;
dis = new DataInputStream((InputStream)this);
}
public final long readLong() throws IOException, EOFException
{
return dis.readLong();
}
public final double readDouble() throws IOException, EOFException
{
return dis.readDouble();
}
public final int readInt() throws IOException, EOFException
{
return dis.readInt();
}
public final int readUnsignedShort() throws IOException, EOFException
{
return dis.readUnsignedShort();
}
public final float readFloat() throws IOException, EOFException
{
return dis.readFloat();
}
public final short readShort() throws IOException, EOFException
{
return dis.readShort();
}
public final char readChar() throws IOException, EOFException
{
return (char)dis.readByte();
}
public void skipBytes(int n) throws IOException
{
int num_bytes_to_skip = n;
int x = 0;
do {
x = dis.skipBytes(num_bytes_to_skip);
num_bytes_to_skip -= x;
} while (num_bytes_to_skip>0);
}
}
// And how the UDP client gets data
// try - catch blocks are omitted for clarity
DatagramPacket pkt = new DatagramPacket(buffer, buffer.length);
socket.receive(pkt);
byte[] data = pkt.getData();
StructureInputStream t = new StructureInputStream(data);
float a1 = t.readFloat(); t.skipBytes(4);
float a2 = t.readFloat(); t.skipBytes(4);
float a3 = t.readFloat(); t.skipBytes(4);
float a4 = t.readFloat(); t.skipBytes(4);
// print out ...
Again, thank you all for your advice.
Regards,