Java实现htonl

时间:2010-04-20 14:32:52

标签: java io endianness

我正在与服务器通信,发送到服务器的每条消息都必须用消息的长度填充,

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

在C中运行htonl的长度并填充消息有效,在Java AFAIK字节顺序已经是网络顺序所以我假设我所要做的就是将消息前的字符串长度写入流,但这不起作用,我错过了什么?

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

Stream是OutputStream

4 个答案:

答案 0 :(得分:12)

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

可选地

int htonl(int value) {
  if (ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN) {
     return value;
  }
  return Integer.reverseBytes(value);
}

答案 1 :(得分:1)

您的实现问题是,write-method只写入一个字节,请参阅documentation。这里的重要句子是:'b的24个高位被忽略。'所以stream.write(msg.length());可能不会做预期的事情。 (我假设msg.length()返回一个int,如果我在这里错了,请纠正我。)

尝试编写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);

首先写入最低有效字节,如果希望可以更改顺序。您可以使用位移转换为字节,对我来说分区看起来更容易理解,但这是个人品味的问题。

答案 2 :(得分:1)

看看方法Int.reverseBytes(),它在x86等平台上将被绑定到x86的bswapl操作码。

你可以根据 System.getProperty(“sun.cpu.endian”)

的结果来解决这个问题。

答案 3 :(得分:0)

并且int在Java平台上没有在运行时指定字节顺序,因为没有办法直接观察代表任何值的位模式。 然而以某种方式将int(或其他)值转换为byte[]的方法具有已定义的转化。

因此,该值的正确传输/接收取决于对byte[]的正确编码/解码。只要您没有告诉我们您是如何做到这一步的,我们就无法帮助您正确地完成这一步骤。