将32位网络顺序转换为用C托管

时间:2019-04-18 14:24:50

标签: c sockets

我正在尝试将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 个答案:

答案 0 :(得分:5)

这看起来很简单:

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 :(得分:1)

这就是我要做的。请注意,使用ntohl()将数据从network-endian转换为host-endian形式:

#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");

答案 2 :(得分:1)

某些操作系统(带有glibc,BSD的Linux)也具有size-specific字节序转换功能,以补充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);
}

编辑:

但是,由于您似乎可以轻松访问各个字节,因此总会有Rob Pike的preferred approach

uint32_t host_int = (file_buf[3]<<0) | (file_buf[2]<<8) | (file_buf[1]<<16) | (file_buf[0]<<24);