Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Implementing htonl

I am communicating with a server, each message sent to the server has to be padded with the length of the message,

unsigned int len = htonl(msg.size());

In C running the length through htonl and padding the message works, in Java AFAIK byte order is already in network order so I assumed all I have to do is write the string length before the message to the stream, but this does not work am I missing something?

stream.write(msg.length());
stream.write(msg.getBytes());

Stream is an OutputStream.

like image 365
Hamza Yerlikaya Avatar asked Apr 20 '10 14:04

Hamza Yerlikaya


3 Answers

int htonl(int value) {
  return ByteBuffer.allocate(4).putInt(value)
    .order(ByteOrder.nativeOrder()).getInt(0);
}

Alternatively

int htonl(int value) {
  if (ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN) {
     return value;
  }
  return Integer.reverseBytes(value);
}
like image 141
Tim Avatar answered Oct 14 '22 13:10

Tim


Problem with your implementation is, that the write-method writes only one byte, see the documentation. The important sentence here is: 'The 24 high-order bits of b are ignored.' So stream.write(msg.length()); probably doesn't do what is intended. (I assume msg.length() returns an int, correct me if I'm wrong here.)

Try to write the four bytes of an int:

stream.write(msg.length() % 256);
stream.write((msg.length() / 256) % 256);
stream.write((msg.length() / (256 * 256)) % 256);
stream.write((msg.length() / (256 * 256 * 256)) % 256);

That writes the least significant byte first, you can change the order if wished. You can do the converting to bytes also with bit-shifting, division looks more understandable for me, but that is a question of personal taste.

like image 41
Mnementh Avatar answered Oct 14 '22 14:10

Mnementh


Take a look at the method Int.reverseBytes(), which on platforms such as x86 will get jitted to the x86's bswapl opcode.

You could condition this off the result of System.getProperty("sun.cpu.endian")

like image 1
srparish Avatar answered Oct 14 '22 13:10

srparish