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

标签 c++

This question on SO主要从严格别名规则的角度处理char <-> uint8_t问题。粗略地说,它阐明了只要将uint8_t实现为charunsigned char,我们就可以了。
我想了解使用uint8_tcharreinterpret_cast的有符号/无符号性可能不兼容的问题。
当我需要直接处理字节时,我更喜欢使用uint8_t。但是,Winsock API处理char*
我想了解如何正确处理这些转换,以免发生 undefined 行为或其他损害应用程序可移植性的现象。
以下函数采用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);
}
它似乎可以在我的机器上运行。但是-这样安全吗?如果我没记错的话,在另一台机器或编译器上,char可能是signed,这意味着转换后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
}

关于c++ - 将传入网络 `char*`数据转换为 `uint8_t`并返回的安全方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62499439/

相关文章:

c++ - Qt 无法打开文件 'sqlite3.lib'

c++ - 为什么 std::is_constructible 在直接上下文中停止?

c++ - 扫描线多边形填充算法

c++ - 从 Linux 动态库/Linux 控制台应用程序导出/导入 C++ 函数 | Visual Studio Linux 项目

c++ - 是否可以在类的构造期间将静态函数分配给公共(public)成员函数?

c++ - 按比例分配两个整数

c++ - 构建此数据结构的最佳方法

c++ - 从 C++ 中的基类访问子数据

C++:如何使用名称长度从内存中的字符指针中取消引用多个字符

c++ - c++思维中遇到的友元迭代器和友元类迭代器有什么区别?