作者热门文章
- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试接收 TCP 套接字的消息并将其存储在 uint8_t
数组中。我要接收的缓冲区是 8 个字节长,包含 4 个唯一值。字节 1:值 1,它是一个 uint8_t,字节 2-3:值 2,它是一个 uint16_t,字节 4:值 3,它是一个 uint8_t,字节 5-8:值 4,它是一个无符号长整型。字节顺序是大端顺序。
int numBytes = 0;
uint8_t buff [8];
if ((numBytes = recv(sockfd, buff, 8, 0)) == -1)
{
perror("recv");
exit(1);
}
uint8_t *pt = buff;
printf("buff[0] = %u\n", *pt);
++pt;
printf("buff[1] = %u\n", *(uint16_t*)pt);
但是第二个 printf
打印出一个意外的值。我提取这两个字节的操作有误还是我的打印功能有问题?
最佳答案
一旦您的数据到达缓冲区,您有 2 个问题需要处理。
首先是遵守别名规则,这是通过仅将非 char 类型指针转换为 char*
来实现的,因为 char
可以别名 任何。您应该永远不要将 char*
转换为非 char 类型指针。
第二个是遵守网络字节排序协议(protocol),通过网络传输的整数在传输前转换为网络顺序,并在接收后从网络顺序转换。为此,我们通常使用 htons
、htonl
、ntohs
和 ntohl
。
像这样:
// declare receive buffer to be char, not uint8_t
char buff[8];
// receive chars in buff here ...
// now transfer and convert data
uint8_t a;
uint16_t b;
uint8_t c;
uint32_t d;
a = static_cast<uint8_t>(buff[0]);
// always cast the receiving type* to char*
// never cast char* to receiving type*
std::copy(buff + 1, buff + 3, (char*)&b)
// convert from network byte order to host order
b = ntohs(b); // short version (uint16_t)
c = static_cast<uint8_t>(buff[3]);
std::copy(buff + 4, buff + 8, (char*)&d)
d = ntohl(d); // long version (uint32_t)
关于c++ - 如何从 uint8_t 数组中提取不同大小的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40332770/
我是一名优秀的程序员,十分优秀!