Преобразование uint32_t в сетевой порядок байтов - PullRequest
0 голосов
/ 22 января 2012

я делаю вещи для учебы, так что да, это домашнее задание .

Первое: у меня есть работающее приложение на сервере Java, у меня также было это клиентское приложение, которое я пишу на c, теперь работающее в Java. Все просто, я не могу отправить uint32_t на мой сервер Java.

Итак, давайте покажем немного кода:

char* callString(char func, char* str, uint32_t anz) {

  uint32_t packageLength, funcLength, strLength;
  funcLength = htonl(sizeof(func));
  strLength = htonl(strlen(str));
  uint32_t byte = htonl(4);
  uint32_t trailing = htonl(1);
  anz = htonl(anz);

  packageLength = byte + byte + funcLength + byte + strLength + byte + byte + trailing;
  /*packageLength = htonl(packageLength);*/

  char byteBuffer[ntohl(packageLength)];


  printf("%i\n", packageLength);
  printf("%i\n", htonl(packageLength));
  printf("%i\n", ntohl(packageLength));

  sprintf(byteBuffer, "%i%i%c%i%s%i%i%c", packageLength, byte, func, byte, str, byte, anz, '\0');

  printf("%s\n", byteBuffer);

  if(write(sock, byteBuffer, packageLength) < 0) {
    printf("write: Konnte keine Daten zum gegenüber senden.\n");
    exit(EXIT_FAILURE);
  }
  char* retVal = "hallo";
  return retVal;
}

Все просто, я вызываю эту функцию с помощью func = 'v', str = "hallo" и anz = 2. который даст мне длину пакета 27 байтов.

Пакет построен следующим образом:
= packageLength (int), 4 байта
+ длина дескриптора функции (funcLength), которая составляет 4 байта
+ дескриптор func (func), который является funcLength
+ длина param1 (strLength), которая составляет 4 байта
+ длина значения param1 (str), равного strLength
+ длина param2, которая составляет 4 байта
+ длина значения param2 (anz), которое составляет 4 байта
+ NULL байт (\ 0), который равен 1 байту

Я предполагаю, что преобразование, которое я делаю, является неправильным, возможно, я использую неправильный тип данных. На стороне сервера я использую Java ByteBuffer для сбора данных. Сначала я прочитал 4-байтовую длину пакета из сети, которая даст мне информацию о том, сколько времени мне нужно читать, пока я не получу весь пакет данных:

byte[] msgLength = new byte[4];
try {
handle.getInputStream().read(msgLength);
} catch (IOException ex) {
    System.out.println("could not receive byte stream: msgLength");
    break;
}
ByteBuffer receive;

receive = ByteBuffer.wrap(msgLength);

int packageLength = receive.getInt();
System.out.println("packageLength" + packageLength);

Последнее println даст мне следующий вывод:

packageLength875901497

Так кто-нибудь сейчас, где моя проблема? При необходимости я могу предоставить вам больше кода, но я думаю, что ошибка - это тип данных (uint32_t) или преобразование.

Помощь оценена. Заранее спасибо.

Приветствие Daniel

1 Ответ

2 голосов
/ 22 января 2012
funcLength = htonl(sizeof(func));
strLength = htonl(strlen(str));
uint32_t byte = htonl(4);
uint32_t trailing = htonl(1);
anz = htonl(anz);

packageLength = byte + byte + funcLength + byte + strLength + byte + byte + trailing;

Вы конвертируете размеры в сетевой порядок, а затем складываете их вместе для packageLength. Вы должны сложить их вместе перед преобразованием их в сетевой порядок с htonl.

Кроме того, все это:

sprintf(byteBuffer, "%i%i%c%i%s%i%i%c", packageLength, byte, func, byte, str, byte, anz, '\0');

неверно, поскольку я предполагаю, что вы хотите отправить их в двоичном виде, но использование sprintf, как указано выше, отправит их в базовом представлении ASCII 10 (т.е. вы отправляете числа в виде текста!)

...