将传入的网络"char*"数据转换为"uint8_t"并返回的安全方法是什么?

What is the safe approach to convert incoming network `char*` data to `uint8_t` and back

本文关键字:quot 返回 方法 是什么 uint8 安全 数据 网络 char 转换      更新时间:2023-10-16

关于SO的这个问题主要从严格混叠规则的角度处理char<>uint8_t问题。粗略地说,它澄清了只要uint8_t实现为charunsigned char,我们就没问题。 我有兴趣了解在使用reinterpret_cast时,uint8_tchar的有符号/无符号的可能不兼容是否重要。

当我需要直接处理字节时,我更喜欢使用uint8_t.但是,Winsock API 处理char*s。

我想了解如何正确处理这些转换,以免遇到未定义的行为或其他损害应用程序可移植性的现象。

以下函数获取std::array<uint8_t, 4>并将其转换为uint32_t- 即,获取 4 个字节并将它们转换为整数。

uint32_t bytes_to_u32(const std::array<uint8_t, 4>& bytes) {
return (bytes[0] << 24) + (bytes[1] << 16) + (bytes[2] << 8) + bytes[3];
}

但是,从套接字传入的数据(使用recv函数(以char*形式出现。

一种方法如下:

std::array<uint8_t, 4> length_buffer;
int bytes_received = 0;
while (bytes_received < 4) {
bytes_received += recv(sock, reinterpret_cast<char*>(length_buffer.data()) + bytes_received, 4 - bytes_received, 0);
}

它似乎在我的机器上工作。但是 - 这安全吗?如果我没记错的话,在不同的机器或编译器上,可能会signedchar,这意味着length_buffer在转换后将保留错误的值。我错了吗?

我知道reinterpret_cast根本不会改变位模式 - 它使二进制数据保持不变。知道了这一点,它仍然没有完全记录在我的大脑中,这种技术是否是正确的方法。

请解释如何处理这个问题。

编辑:还请注意,将char*转换为uint8_t*后,我需要能够将uint8_t*转换为有效的数值,或者有时测试缓冲区中单个字节的数值。为了解释"命令",我通过网络发送,并将一些发送回另一端。

我希望我确实正确理解了您的问题,您可以使用联合来解决此问题:

//Union is template so you can use this for any given type
template<typename T>
union ConvertBytes
{
T value;
char byte[sizeof(T)];
};
void process()
{
recv(socket, buffer, bufferLength, 0); //Recieve data
ConvertBytes<uint32_t> converter;
for (int i = 0; i < sizeof(uint32_t); i++) //Considering that you recieve only that one uint32
{
converter.byte[i] = buffer[i]; //Assign all bytes into union
}
uint32_t result = converter.value; //Get uint32_t value from union
}