Issue
I have an application in which I'm trying to send UDP messages using TSLv5. The protocol is somewhat complicated, but to do it I need to write 16 bit values as little-endian and then send that via UDP.
Here's my code doing just that:
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.putShort(SCREEN_POS, screen);
buffer.putShort(INDEX_POS, index);
ByteBuffer text = ByteBuffer.wrap(value.getBytes());
short textLength = (short) value.getBytes().length;
buffer.putShort(LENGTH_POS, textLength);
ByteBuffer combined = ByteBufferUtils.concat(buffer, text);
short control = 0x00;
control |= rhTally << 0;
control |= textTally << 2;
control |= lhTally << 4;
control |= brightness << 6;
combined.putShort(CONTROL_POS, control);
short msgLength = (short) (combined.array().length - 2);
combined.putShort(PBC_POS, msgLength);
return new DatagramPacket(combined.array(), combined.array().length, ip, 9000);
This mostly works, but the problem is when I have values that are greater than 127.
For example, my index is 148
and when all is said and done, my control comes out to be 193
. When I write those values to the ByteBuffer they become -108
and -63
, respectively.
I know why this happens, a ByteBuffer is an array of bytes and bytes can't be greater than 127. What I don't know is how I can achieve this? The protocol does not work if I send signed values, it has to be the exact number.
Solution
I can assure that a signed java byte will be read correctly in the two bytes of a short. I have simplified the code, writing the fields one after the other in linear fashion, with message fields in front. Also just used one ByteBuffer.
(Maybe there is some small error like a wrong offset.)
Also I send the text bytes as being in UTF-8. You used the implicit platform encoding, which may differ on every computer.
byte[] text = value.getBytes(StandardCharsets.UTF_8);
int textLength = text.length;
int length = 2 + 2 + 2 + 2 + 2 + textLength;
ByteBuffer buffer = ByteBuffer.allocate(length)
.order(ByteOrder.LITTLE_ENDIAN);
short control = 0x00;
control |= rhTally << 0;
control |= textTally << 2;
control |= lhTally << 4;
control |= brightness << 6;
buffer.putShort(/*CONTROL_POS,*/ control);
short msgLength = (short) (length - 2);
buffer.putShort(/*PBC_POS,*/ msgLength);
buffer.putShort(/*SCREEN_POS,*/ screen);
buffer.putShort(/*INDEX_POS,*/ index);
buffer.putShort(/*LENGTH_POS,*/ (short)textLength);
buffer.put(text, 0, textLength);
return new DatagramPacket(buffer.array(), length, ip, 9000);
Answered By - Joop Eggen
Answer Checked By - Timothy Miller (JavaFixing Admin)