UDP接收数据为unsigned char

时间:2016-06-07 08:31:32

标签: c++ c sockets udp

我试图使用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

2 个答案:

答案 0 :(得分:3)

看起来您可能获得了正确的值,但是在打印期间您向short int转换符号扩展了您的字符值,导致ff被传播到顶部字节,如果您的顶部位char为1(即为负)。您应该首先将其强制转换为无符号类型,然后扩展为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;
   }

答案 1 :(得分:3)

当您将数据存储在有符号数据类型中时,转换/提升为更大的数据类型将首先签署扩展值(使用MSB的值填充高位),即使它随后转换为无符号数据类型。

  • 一种解决方案是将recvline定义为uint8_t[],并将char*传递给recvfrom时将其转换为uint8_t[]。这样,你只需要抛出一次,你在windows和linux版本中使用相同的代码。另外(recvline[i] & 0xff)(至少对我来说)清楚地表明你正在使用数组作为原始内存而不是某种字符串。

  • 另一种可能性是简单地执行按位和:Control source。由于自动积分推广,这甚至不需要演员。

个人注意事项:
真的很烦人的是,C和C ++标准没有为原始内存提供单独的类型(但是),但幸运的是,在未来的标准版本中可以获得byte类型。