发送固定长度的标头

时间:2014-07-29 17:01:23

标签: c++ qt sockets

我尝试使用固定长度的标头发送数据,该标头告诉服务器在读取数据之前必须读取多少字节的数据。不过,我在这方面遇到了麻烦。我希望一次能够发送的最大数据字节数为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始终为两个字节,即使数字<255?

1 个答案:

答案 0 :(得分:3)

你的

 clientSendBuf.prepend(bytes);

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

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

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