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
.
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);
}
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.
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")
And int
has no specified byte ordering at runtime in the Java platform, simply because there is no way to directly observe the bit pattern representing any value. However methods that somehow convert int
(or other) values to byte[]
have a defined conversion.
So the correct transmission/reception of that value depends on the correct encoding/decoding to/from byte[]
. As long as you don't tell us how you do that step, we can't help you do it correctly.
精彩评论