【问题标题】:Interpreting Char-Array to Multiple concatenated Datatypes将字符数组解释为多个连接的数据类型
【发布时间】:2015-05-23 18:23:59
【问题描述】:

我通过 Socket 接收字节流(或 C++ 中的字符)。现在我想解释它们。我知道哪些数据类型隐藏在字节后面。我的消息看起来像这样:

value1   --> char (1 byte)
value2   --> long (8 bytes)
value3   --> short (2 bytes)
... 

我怎样才能有效地实现口译?

//编辑:那不行,字节不是描述字符而是整数。

我想过用 memcpy 和 atoi 做(目前还没有测试):

char value1 = *charPtr;
charPtr++;

char value2[8]="";
std::memcpy(charPtr,value2,8);
long v2 = atoi(value2);
charPtr+=8;

char value3[2]="";
std::memcpy(charPtr,value3,2);
short v3 = atoi(value3);
charPtr+=2;

【问题讨论】:

  • 您是否考虑过使用 std::stringstream 及其运算符>> 来获取数据?
  • char* 中的数据不是字符,所以我认为 stringstream 行不通。

标签: c++ arrays casting char byte


【解决方案1】:

我假设您正在尝试以原始字节流的形式发送数据,并且您确信发送方和接收方使用相同的浮点格式相同的终结性 .

但是你打包的数据流显然违反了发送方和接收方的对齐规则,所以我们不能做类似value2 = *(long *)data;的事情

所以,尝试使用parsePackedStruct(data, &value1, &value2, &value3);

一个合理的实现可以是:

void parsePackedStruct(char *data, char *pValue1, long *pValue2, short *pValue3)
{
    memcpy(pValue1, data, sizeof(*pValue1));
    data = data + sizeof(*pLalue1);
    memcpy(pValue2, data, sizeof(*pValue2));
    data = data + sizeof(*pLalue2);
    memcpy(pValue3, data, sizeof(*pValue3));
}

这要求您的发送者和接收者对于char/short/long 具有严格相同的大小,这对我来说似乎过于严格,因为long 的大小因平台而异比其他算术类型更频繁。出于同样的原因,我也会避免使用bool 并使用uint8_t

因此请考虑 C99 整数类型,例如 int32_t

【讨论】:

    【解决方案2】:

    假设发送方和接收方在发送/接收的原始数据方面完全同步,您可以执行以下操作:

    #pragma pack(push, 1)
    struct MyPackedData {
      char c;
      long l;
      short s;
    };
    #pragma pack(pop)
    

    ...

    MyPackedData parsedData;
    memcpy(&parsedData, charPtr, sizeof(parsedData));
    

    【讨论】:

      【解决方案3】:

      好的,我想出了如何做到这一点。关键字是位移:

      long readAndSkipLong(char*& b)
      {
          unsigned long ret = (b[0] << 56) | (b[1] << 48) | (b[2] << 40) | (b[3]<<32) | (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
          b+=8;
          return ret;
      }
      
      int readAndSkipInt(char*& b)
      {
          int32_t ret = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
          b+=4;
          return ret;
      }
      
      short readAndSkipShort(char*& b) {
          short ret =  (b[0] << 8) | (b[1]);
          b+=2;
          return ret;
      }
      
      ...
      while (readChar(it)!='#') // stop at the terminating char
      {
              readAndSkipShort(it);
              readAndSkipInt(it);
      }
      ...
      

      尽管如此,我的 long 和 int 转换似乎并不正确。对于预期值

      152  --> 00000000 00000000 00000000 00000000 00000000 00000000 00000000 10011000
      

      我解释:

      -104  --> 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10011000 
      

      知道错误在哪里吗?

      【讨论】:

        猜你喜欢
        • 2012-02-22
        • 1970-01-01
        • 2021-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-17
        相关资源
        最近更新 更多