【问题标题】:Sending a fixed-length header发送固定长度的标头
【发布时间】:2014-07-30 01:15:50
【问题描述】:

我正在尝试发送带有固定长度标头的数据,该标头告诉服务器在读取数据之前必须读取多少字节的数据。不过,我在这样做时遇到了麻烦。我希望一次能够发送的最大数据字节数是 65536,所以我发送一个 uint16_t 类型变量作为我的数据的标头,因为它可以表示的最大数量是 65536。

问题是,uint16_t 占用两个字节,而小于 255 的数字只占用一个字节。所以我在客户端有这段代码:

uint16_t messageSize = clientSendBuf.size(); //clientSendBuf is the data I want to send
char *bytes((char*)&messageSize);
clientSendBuf.prepend(bytes);
client.write(clientSendBuf);

在服务器上,我处理接收这样的消息:

char serverReceiveBuf[65536];
uint16_t messageSize;
client->read((char*)&messageSize, sizeof(uint16_t));
client->read(serverReceiveBuf, messageSize);

我稍后会改变这个,因为它不是最好的解决方案(特别是当所有数据都不可用时),但我想先解决这个问题。我的问题是,当clientSendBuf.size() 太小(在我的测试用例中是 16 个字节,我假设每个低于 255 的值都会发生这种情况)使用

读取数据时
client->read((char*)&messageSize, sizeof(uint16_t));

读取不属于标头的第二个字节,为messageSize 提供不正确的值并导致服务器崩溃。如果我将sizeof(uint16_t) 替换为1,那么服务器会按照我的预期正常读取数据,尽管那时我的messageSize 最大值为255,这比我想要的要低得多。如何使messageSize 前面的clientSendBuf 始终是两个字节,即使对于数字

【问题讨论】:

  • 为什么即使发送缓冲区很小,标题 still 也不是 16 位(两个字节)?即使您只有一个字节的数据要发送,那么您应该仍然发送两个字节的固定标头。
  • @JoachimPileborg 你告诉我。我也是这么想的,但是当我发送一个小的messageSize(并通过调试检查)时,服务器端messageSize的值与客户端发送的messageSize不一样。此外,serverReceiveBuf 中的数据与发送的数据不匹配,相差一个字节(第一个字节是我期望的第二个字节)。当我将sizeof(uint16_t) 更改为1 时,一切都很好,但我被限制为255 个字节,这还不够好。我的问题是如何确保标题总是两个字节,即使messageSize 需要一个
  • 还请考虑endianess issues,当您以这种方式在客户端和服务器之间交换数字数据时可能会发生这种情况。我建议将 uint16_t 值始终转换为网络字节顺序(即大端)。
  • 那你需要先看看prepend函数是做什么的,是不是只加了一个一个字节?我对此表示怀疑,因为它不需要添加多个字节。接下来,您可能想看看write 函数的作用。
  • @JoachimPileborg 无论数据需要多少字节,它都会预先添加。所以当我使用char *bytes((char*)&messageSize); 并且messageSize *bytes 只需要一个字节来存储,这就是前面的所有内容。我还能如何发送固定长度的标头?

标签: c++ qt sockets


【解决方案1】:

你的

 clientSendBuf.prepend(bytes);

还应该告诉它需要发送2个字节;现在它是treats the bytes as a zero-terminated string,因为在您的平台上,0x0010 的第二个字节为零(使用 little-endian 数字:0x16、0x00),所以它意外地起作用了。

prepend(char*, int) method 可以解决问题:

// use this instead:
cliendSendBuf.prepend(bytes, sizeof(messageSize));

【讨论】:

  • 我明白这一点,但我的问题是 如何 我如何让 prepend() 总是 前置两个字节,即使 *bytes 只需要一个字节?或者更确切地说,我还能如何发送固定长度的标头?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
  • 2016-08-11
相关资源
最近更新 更多