Java实现htonl

Ham*_*aya 5 java io endianness

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

unsigned int len = htonl(msg.size());
Run Code Online (Sandbox Code Playgroud)

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

stream.write(msg.length());
stream.write(msg.getBytes());
Run Code Online (Sandbox Code Playgroud)

流是一个OutputStream.

Tim*_*Tim 12

int htonl(int value) {
  return ByteBuffer.allocate(4).putInt(value)
    .order(ByteOrder.nativeOrder()).getInt(0);
}
Run Code Online (Sandbox Code Playgroud)

另外

int htonl(int value) {
  if (ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN) {
     return value;
  }
  return Integer.reverseBytes(value);
}
Run Code Online (Sandbox Code Playgroud)


Mne*_*nth 2

您的实现问题是,写入方法仅写入一个字节,请参阅文档。这里重要的一句话是:“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);
Run Code Online (Sandbox Code Playgroud)

首先写入最低有效字节,如果愿意,您可以更改顺序。您也可以通过位移位来转换为字节,除法对我来说看起来更容易理解,但这是个人品味的问题。