我正在尝试使用POCO::Net通过网络将某些对象从一个程序发送到另一个程序,以处理连接,使用 Cereal 来处理序列化。

所有数据包均继承自单一基础BasePacket。

class BasePacket {};
typedef std::shared_ptr<BasePacket> BasePacketPtr;

这是我发送数据的方式:
Poco::Net::StreamSocket &socket; //passed as an argument
Poco::Net::SocketOutputStream os(socket);
while (!sendQueue.empty()) {
    BasePacketPtr v;
    v = sendQueue.front();
    { //block to make sure that cereal flushes everything
     cereal::BinaryOutputArchive oa(os);
     oa << v;
    }
    sendQueue.pop();
}
os.flush();

这就是我接收数据的方式:
Poco::Net::StreamSocket &socket; //passed as an argument
Poco::Net::SocketInputStream is(socket);
cereal::BinaryInputArchive ia(is);
BasePacketPtr v;
while(socket.available()) {
    ia >> v;
    //do sth with v...
}

问题在于,当数据发送速度非常快时,套接字缓冲区中可能会等待许多数据包,并且 Cereal 会读取所有字节,但只会反序列化第一个数据包,而其他数据包则会丢失。

有没有一种方法可以使 Cereal 一次只能读取一个数据包,或者反序列化多个数据包?还是我应该在Poco的套接字流和 Cereal 的存档之间建立某种缓冲区,以发送数据大小,以便它可以一次读取一个数据包,然后再传递给 Cereal ?

最佳答案

如果有人碰巧遇到相同的问题,这是问题的原因:

while(socket.available())

即使缓冲区中有多个数据包,此操作也只会迭代一次( Cereal 归档文件从套接字获取了所有数据,因此它没有任何可用数据,因此返回0)。

当出现新的数据包时,缓冲区将重置并且数据将丢失。

解决方案是在没有更多数据之前,继续从 Cereal 成就中读取数据。如果它在单独的线程中运行,则即使while(isRunning()){ia >> v; /.../ } 足够的。

关于c++ - 在C++中用POCO和谷类对多个对象进行反序列化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51309413/

10-10 17:25