UDP以无符号字符的形式接收数据
UDP receive data as unsigned char
我正在尝试使用UDP从网络接收一些数据并对其进行解析。
这是代码,
char recvline[1024];
int n=recvfrom(sockfd,recvline,1024,0,NULL,NULL);
for(int i=0;i<n;i++)
cout << hex <<static_cast<short int>(recvline[i])<<" ";
打印输出,
19 ffb0 0 0 ff88 d 38 19 48 38 0 0 2 1 3 1 ff8f ff82 5 40 20 16 6 6 22 36 6 2c 0 0 0 0 0 0 0 0
但我期待着这样的输出
19 b0 0 0 88 d 38 19 48 38 0 0 2 1 3 1 8f 82 5 40 20 16 6 6 22 36 6 2c 0 0 0 0 0 0 0 0
ff
不应该出现在打印输出上。
事实上,我必须根据每个字符来解析这些数据,
比如
parseCommand(recvline);
解析代码看起来,
void parseCommand( char *msg){
int commId=*(msg+1);
switch(commId){
case 0xb0 : //do some operation
break;
case 0x20 : //do another operation
break;
}
}
在调试时,我正在监视commId=-80
。
注意:在Linux中,我成功地输出了代码,请注意,我使用了unsigned char
而不是char
作为读取缓冲区。
unsigned char recvline[1024];
int n=recvfrom(sockfd,recvline,1024,0,NULL,NULL);
在Windows recvfrom()中,不允许第二个参数为unsigned
,它给出了构建错误,所以我选择了char
看起来您可能得到了正确的值,但在打印符号期间对short int
的强制转换扩展了您的char值,如果char
的顶部位为1(即为负数),则会导致ff
按比例分配到顶部字节。您应该首先将其强制转换为无符号类型,然后扩展为int,因此需要2个强制转换:
cout << hex << static_cast<short int>(static_cast<uint8_t>(recvline[i]))<<" ";
我已经对此进行了测试,它的性能与预期一致。
响应您的扩展:读取的数据很好,这是您如何解释它的问题。要正确解析,您应该:
uint8_t commId= static_cast<uint8_t>(*(msg+1));
switch(commId){
case 0xb0 : //do some operation
break;
case 0x20 : //do another operation
break;
}
当您将数据存储在带符号的数据类型中时,转换/提升到更大的数据类型将首先对值进行符号扩展(用MSB的值填充高位),即使它随后被转换为无符号数据类型。
-
一种解决方案是首先将
recvline
定义为uint8_t[]
,并在将其传递给recvfrom
函数时将其强制转换为char*
。这样,您只需要对其进行一次强制转换,并且在windows和linux版本中使用相同的代码。此外,uint8_t[]
(至少对我来说)清楚地表明,您正在使用数组作为原始内存,而不是某种字符串。 -
另一种可能性是简单地执行按位And:
(recvline[i] & 0xff)
。由于自动整体升级,这甚至不需要演员阵容。
个人注意:
C和C++标准还没有为原始内存提供单独的类型,这真的很烦人,但如果运气好的话,我们在未来的标准修订版中会得到byte
类型。
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 在 std::vector<无符号字符中存储任意数据的方法>
- 一种将 Dart 中的字节数据转换为 C++ 中的无符号字符*的有效方法?
- C++ C4244 =':从"std::streamsize"转换为"无符号短",可能会丢失数据;有什么解决办法吗?
- 使用二进制数据和无符号字符
- QT QT QBYTEARRAY无符号数据类型
- 给定一个填充无符号字符**的 C 函数,如何在没有中间副本的情况下用数据填充 std::vector
- 从 T 转换为无符号 int,可能会丢失数据
- 将数据从 vector<unsigned char> 传输到无符号 char[]
- UDP以无符号字符的形式接收数据
- C/C++为什么对二进制数据使用无符号字符
- 如何以最佳方式将高分辨率图像数据存储在无符号字符*中C++
- 从 std::vector<无符号字符中的数据填充结构>
- 为什么从无符号long-long转换为double会导致数据丢失
- 表示本机有符号和无符号整数大小的数据类型
- 使用无符号数据类型强制执行非负值和/或有效值是否是一种最佳做法
- 警告 1 警告 C4244:"参数":从"time_t"转换为"无符号 int",可能会丢失数据以及其他错误
- 用于确定有符号和无符号数据类型C++的范围的公式
- 警告 C4244:'argument':从 'time_t' 转换为"无符号 int",可能会丢失数据 -- C++
- 无符号char*数据作为c++或c中函数的返回类型