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