C ++ / C:以字节为前缀的长度为Char [](二进制/十六进制)

时间:2017-10-24 10:02:07

标签: c++ c type-conversion udp hex

我希望从客户端向服务器发送UDP数据报,然后再回来。

服务器需要以字节格式向每个数据报(表示为Tile[])添加标头,我很难找到它的示例。我知道如何将它作为实际文本字符发送,但我想将其发送为"有效"二进制形式(例如,如果MainActivityBindingpublic boolean setVariable(int variableId, Object variable) { switch(variableId) { case BR.tiles : setTiles((com.myapp.Tile[]) variable); return true; } return false; } ,那么我想要预先加BR.tiles或2字节无符号等价,而不是' 0028& #39;以ASCII char[]形式或类似形式,这将是4个字节而不是潜在的2。

据我所知,我的最佳选择如下:

length

这种方法有效,还是以后会引起问题?

此外,如果我没有弄错的话,这给了我一个255的硬限制。我怎样才能最好地将其表示为2个字节来扩展我的最大长度。

编辑:我需要预先设置每个数据报的长度,因为我将每个数据报构建成一个更大的帧,并且接收者需要能够将帧分成每个信息元素,我认为这意味着我应该需要包含的长度,以便接收者和每个元素结束和下一个元素开始的地方

1 个答案:

答案 0 :(得分:1)

你可能需要这样的东西:

  char somestring[] = "Hello World!";
  char sendbuffer[1000];

  int length = strlen(somestring);
  sendbuffer[0] = length % 0xff;         // put LSB of length
  sendbuffer[1] = (length >> 8) & 0xff;  // put MSB of length

  strcpy(&sendbuffer[2], somestring);    // copy the string right after the length

sendbuffer是将要发送的缓冲区;我将其修复为最大长度为1000,允许发送长度为997的字符串(长度为1000 - 2个字节 - NUL终结符为1个字节)。

LSB表示最低有效字节MSB表示最高有效字节。这里我们把LSB放在第一位,MSB放在第二位,这个约定叫做 little endian ,反过来就是 big endian 。您需要确保在接收器端正确解码长度。如果接收器侧的架构具有除发送器之外的其他字节序,则接收器侧的长度可能根据代码被解码错误。谷歌“endianness”了解更多细节。

sendbuffer在内存中看起来像这样:

 0x0c 0x00 0x48 0x65 0x6c 0x6c ...
|   12    |'H' |'e' |'l' |'l '| ...
  //... Decoding (assuming short is a 16 bit type on the receiver side)

  // first method (won't work if endiannnes is different on receiver side)
  int decodedlength = *((unsigned short*)sendbuffer);       

  // second method (endiannness safe)
  int decodedlength2 = (unsigned char)sendbuffer[0] | (unsigned char)sendbuffer[1] << 8;


  char decodedstring[1000];
  strcpy(decodedstring, &sendbuffer[2]);

可能的优化:

如果您发送的大多数字符串的长度小于255,您可以优化而不是系统地预先设置两个字节,但大部分时间只有一个字节,但这是另一个故事。