Java Реализация htonl - PullRequest
       27

Java Реализация htonl

5 голосов
/ 20 апреля 2010

Я общаюсь с сервером, каждое сообщение, отправленное на сервер, должно быть дополнено длиной сообщения,

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

В C, выполняющем длину до htonl и дополняющем сообщение, работает, в Java порядок байтов AFAIK уже в сетевом порядке, поэтому я предположил, что все, что мне нужно сделать, это записать длину строки до сообщения в поток, но не работает я что-то упустил?

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

Поток - это OutputStream.

Ответы [ 4 ]

12 голосов
/ 21 марта 2013
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 голос
/ 20 апреля 2010

Проблема с вашей реализацией в том, что метод write записывает только один байт, см. Документацию . Важное предложение здесь: «24 старших разряда b игнорируются». Так что stream.write(msg.length());, вероятно, не делает то, что задумано. (Я предполагаю, что msg.length () возвращает 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);

Сначала записывает младший байт, вы можете изменить порядок, если хотите. Вы можете выполнять преобразование в байты также со сдвигом битов, разделение выглядит для меня более понятным, но это вопрос личного вкуса.

1 голос
/ 07 июля 2012

Взгляните на метод Int.reverseBytes () , который на платформах, таких как x86, будет связан с кодом операции bswapl x86.

Вы можете ограничить это результатом System.getProperty ("sun.cpu.endian")

0 голосов
/ 20 апреля 2010

И int не имеют определенного порядка байтов во время выполнения на платформе Java просто потому, что нет способа непосредственно наблюдать битовую комбинацию, представляющую какое-либо значение. Однако методы, которые каким-то образом преобразуют int (или другие) значения в byte[], имеют определенное преобразование.

Таким образом, правильная передача / прием этого значения зависит от правильного кодирования / декодирования в / из byte[]. Пока вы не скажете нам, как вы делаете этот шаг, мы не сможем помочь вам сделать это правильно.

...