如何在Poco C ++中复制缓冲区字节块?

时间:2016-03-15 09:44:46

标签: c++ sockets poco-libraries

您好我正在尝试在poco中编写TCP连接。客户端发送包含以下字段的数据包:

packetSize : int date : 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不是预期的。我尝试流式传输没有块复制并手动接收每个字段没有循环,它很好,并有预期的数据。但是当我尝试将传入的字节存储到一个数组中然后将该数组传递给内存流来读取它时,我只有第一个块正确且预期!!

我真的需要将所有传入的字节存储到一个数组中然后读取整个数组,我应该如何更改我的代码?

非常感谢

1 个答案:

答案 0 :(得分:1)

我在代码中看到两个错误。或者,更确切地说,你做了两次错误。 您将sizeof的{​​{1}}与char[]的{​​{1}}混淆了第一个是数组中的字符数,第二个是指针的大小:通常为4或8个字节,具体取决于内存模型。

所以,当你写

sizeof

你要求4个(我猜)字节。这并不严重,因为在消息完成之前你继续询问其他字节。

真正的问题是以下说明

char *

您只在availableBytes = socket().receiveBytes(bytes, sizeof(bytes), MSG_WAITALL);

中传输Poco::MemoryInputStream *inStream = new Poco::MemoryInputStream(body, sizeof(body)); 个字节

您应该将sizeof(char *)inStream替换为sizeof(body)

P.s:抱歉我的英语不好

编辑:我发现了另一个错误。在这条指令中

sizeof(bytes)

你分配packetSize - 4个字符。此内存从未删除,并在 char *bytes = new char[packetSize - 4]; 周期中分配。

您可以在周期之外分配packetSize - 4(与do ... while()一起使用)。

编辑2016.03.17

建议的解决方案(警告:未经测试)

bytes