将传入的网络"char*"数据转换为"uint8_t"并返回的安全方法是什么?
What is the safe approach to convert incoming network `char*` data to `uint8_t` and back
关于SO的这个问题主要从严格混叠规则的角度处理char
<>uint8_t
问题。粗略地说,它澄清了只要uint8_t
实现为char
或unsigned char
,我们就没问题。 我有兴趣了解在使用reinterpret_cast
时,uint8_t
与char
的有符号/无符号的可能不兼容是否重要。
当我需要直接处理字节时,我更喜欢使用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);
}
它似乎在我的机器上工作。但是 - 这安全吗?如果我没记错的话,在不同的机器或编译器上,可能会signed
char
,这意味着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
}
相关文章:
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何取消对nullptr的屏蔽,返回正确的对象
- 奇怪的结构&GCC&clang(void*返回类型)
- 架构决策:返回std::future还是提供回调
- 从python中调用C++函数并获取返回值
- 矩阵向量乘法(cublasDgemv)返回零
- “并非所有控制路径都返回一个值./&quot“控制可能达到非空隙功能的末端”.验证时循环时