Конвертировать 32-битный сетевой порядок для размещения в C - PullRequest
1 голос
/ 18 апреля 2019

Я пытаюсь преобразовать uint32_t из сетевого порядка байтов в формат хоста. Я читаю из tcp-соединения 4 байта, которые я храню в буфере следующим образом:

ssize_t read = 0;
char *file_buf;
size_t fb_size = 4 * sizeof(char);
file_buf = malloc(fb_size);
read = recv(socket_file_descriptor,file_buf,fb_size,0);

поэтому я храню номер в file_buf, но мне нужен номер, как я могу это сделать?

Ответы [ 3 ]

5 голосов
/ 18 апреля 2019

Это выглядит просто:

ssize_t read = 0;
uint32_t myInteger;  // Declare a 32-bit uint.

// Pass a pointer to the integer, and the size of the integer.
read = recv(socket_file_descriptor,&myInteger,sizeof(myInteger),0);

myInteger = ntohl(myInteger); // Change from Network order to Host order.
1 голос
/ 18 апреля 2019

Некоторые ОС (Linux с glibc, BSD) также имеют специфичные для размера функции преобразования порядка байтов, которые дополняют ntohl() и ntohs().

#include <endian.h> // Might need <sys/endian.h> instead on some BSDs

void your_function(uint32_t bigend_int) {
  uint32_t host_int = be32toh(bigend_int);
}

Edit:

Но так как вы, кажется, имеете легкий доступ к отдельным байтам, всегда есть предпочтительный подход Роба Пайка :

uint32_t host_int = (file_buf[3]<<0) | (file_buf[2]<<8) | (file_buf[1]<<16) | (file_buf[0]<<24);
1 голос
/ 18 апреля 2019

Вот как бы я это сделал. Обратите внимание на использование ntohl() для преобразования данных из порядка сети в форму узла:

#include <stdio.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <sys/socket.h>

[...]

char file_buf[4];
if (recv(socket_file_descriptor,file_buf,fb_size,0) == sizeof(file_buf))
{
   uint32_t * p = (uint32_t *) file_buf;
   uint32_t num = ntohl(*p);
   printf("The number is %u\n", num);
}
else printf("Short read or network error?\n");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...