嗨,我想在poco中写一个TCP连接.客户端发送包含以下字段的数据包:
packetSize:int
日期:int
ID:int
所以前4个字节包含数据包大小.在接收方我有这个代码:
int packetSize = 0;
char *bufferHeader = new char[4];
// receive 4 bytes that contains packetsize here
socket().receiveBytes(bufferHeader, sizeof(bufferHeader), MSG_WAITALL);
Poco::MemoryInputStream *inStreamHeader = new Poco::MemoryInputStream(bufferHeader, sizeof(bufferHeader));
Poco::BinaryReader *BinaryReaderHeader = new Poco::BinaryReader(*inStreamHeader);
(*BinaryReaderHeader) >> packetSize; // now we have the full packet size
现在我试图将所有剩余的传入字节存储到一个数组中以供将来二进制读取:
int ID = 0;
int date = 0;
int availableBytes = 0;
int readedBytes = 0;
char *body = new char[packetSize - 4];
do
{
char *bytes = new char[packetSize - 4];
availableBytes = socket().receiveBytes(bytes, sizeof(bytes), MSG_WAITALL);
if (availableBytes == 0)
break;
memcpy(body + readedBytes, bytes, availableBytes);
readedBytes += availableBytes;
} while (availableBytes > 0);
Poco::MemoryInputStream *inStream = new Poco::MemoryInputStream(body, sizeof(body));
Poco::BinaryReader *BinaryReader = new Poco::BinaryReader(*inStream);
(*BinaryReader) >> date;
(*BinaryReader) >> ID;
cout << "date :" << date << endl;
cout << "ID :" << ID << endl;
问题是正文的字节块没有存储剩余的字节,它始终只有前4个字节(日期).所以在输出中日期是正确的但ID不是预期的.我尝试流式传输没有块复制并手动接收每个字段没有循环,它很好,并有预期的数据.但是当我尝试将传入的字节存储到一个数组然后将该数组传递给内存流来读取它时,我只有第一个块正确且预期!!
我真的需要将所有传入的字节存储到一个数组然后读取整个数组,我应该如何更改我的代码?
非常感谢
最佳答案 我在你的代码中看到了两个错误.或者,更确切地说,你做了两次错误.
你将char []的sizeof与char *的sizeof混淆;第一个是数组中的字符数,第二个是指针的大小:通常为4或8个字节,具体取决于内存模型.
所以,当你写作
availableBytes = socket().receiveBytes(bytes, sizeof(bytes), MSG_WAITALL);
你要求4个(我猜)字节.这并不严重,因为在消息完成之前您继续询问其他字节.
真正的问题是以下说明
Poco::MemoryInputStream *inStream = new Poco::MemoryInputStream(body, sizeof(body));
你在inStream中只传输sizeof(char *)字节的地方
你应该用packetSize – 4替换sizeof(body)和sizeof(bytes).
P.s:抱歉我的英语不好
编辑:我看到了另一个错误.在这个指令中
char *bytes = new char[packetSize - 4];
你分配packetSize – 4个字符.这个内存永远不会删除,并且在do … while()循环中分配.
您可以在循环之外分配字节(与body一起使用).
编辑2016.03.17
建议的解决方案(注意:未经测试)
size_t toRead = packetSize - 4U;
size_t totRead = 0U;
size_t nowRead;
char * body = new char[toRead];
do
{
nowRead += socket().receiveBytes(body+totRead, toRead-totRead,
MSG_WAITALL);
if ( 0 == nowRead )
throw std::runtime_error("shutdown from receiveBytes()");
totRead += nowRead;
} while ( totRead < toRead );
Poco::MemoryInputStream *inStream = new Poco::MemoryInputStream(body,
toRead);
delete[] body;
body = NULL;