Strange problem with DatagramSocket and DatagramPacket.

Hi!

I got a strange problem with UDP sockets:

Client (hardware device) send binary data messages, consisting of bytes and shorts fields (8 and 16 bits). But when I tried to read byte array, received from socket, I got some type anomaly. For example:

byte[] buffer =newbyte[1024];

DatagramPacket packet =new DatagramPacket(buffer, 1024);

socket.receive(packet);

byte[] data = packet.getData();

System.out.println("Received data:");

for (int i = 0; i < packet.getLength(); i++){

System.out.printf("%h:", data[i]);

}

I got such thing: 34:4:fffffff1:ffffffdb:ffffffdc:20:1:1:0:2:50

If I try to parse it using ByteArrayInputStream and DataInputStream

ByteArrayInputStream is =new ByteArrayInputStream(packet.getData());

DataInputStream dis =new DataInputStream(is);

int head = dis.readByte();

int recvinfo = dis.readByte();

short count = (short)dis.readShort();

System.err.printf("Decoded:\n head: %h\n recvinfo: %h\n count: %h\n",

head, recvinfo, count);

i got following:

Decoded:

head: 34

recvinfo: 4

count: fffff1db

So I get Integer entries in byte?! array. I also got Integer even I try to read and cast it as short in short!!! variable.

Please help!

P.S. Sorry for my bad English.

[1940 byte] By [Zeuxa] at [2007-11-27 1:39:31]
# 1
That's just sign extension. Limit the length of what you print to 2 characters.
ejpa at 2007-7-12 0:52:37 > top of Java-index,Core,Core APIs...
# 2

Thanks a lot for your response.

This problem is already solved. This bug is happened when I try to cast byte to int in ways like this:

byte b = 123;

int i = (int)b;

But all is fine, when I use a bit mask for a conversion:

byte b = 123;

int i = (int)(b & 0xff);

or

short s = 1234;

int i = (int)(s & 0xffff);

for short.

Zeuxa at 2007-7-12 0:52:37 > top of Java-index,Core,Core APIs...
# 3

> byte b = 123;

> int i = (int)b;

>

which is meaningless, or rather pointless. You could leave the cast out and the same thing would happen.

> byte b = 123;

> int i = (int)(b & 0xff);

>

> or

>

> > short s = 1234;

> int i = (int)(s & 0xffff);

>

>

> for short.

The (int) part of both of these is equally pointless.

ejpa at 2007-7-12 0:52:37 > top of Java-index,Core,Core APIs...
# 4

Rather fortunate that it auto-casts(or rather, that 0xFF is int by default, rather than attempting any type-detection as most languages do), as otherwise the brackets would have been in the wrong place. If it was still a byte after the "& 0xFF", sign extension would still occur.

For the sake of the less bit-literate reading this thread, it should be explained that the reason for this was large bytes being interpreted as negative numbers, which translate to negative int, which in hexa become very large ints. That's about as verbose as I can be about this without writing the equivalent of a wikipedia entry about 2s complement.

SlugFillera at 2007-7-12 0:52:37 > top of Java-index,Core,Core APIs...