1

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

所有数据包都继承自单个基础 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...
}

问题是当数据发送非常快时,许多数据包可能在套接字缓冲区中等待,并且谷物读取所有字节,但仅反序列化第一个数据包而其余数据包丢失。

有没有办法让谷物当时只读取一个数据包或反序列化多个数据包?或者我应该在 Poco 的 socketstream 和谷物的存档之间建立某种缓冲区来发送数据大小,以便它可以在将一个数据包传递给谷物之前同时读取一个数据包?

4

1 回答 1

0

万一有人碰巧遇到同样的问题,问题的原因如下:

while(socket.available())

即使缓冲区中有多个数据包,这只迭代一次(谷物存档从套接字获取所有数据,因此它没有任何可用数据,因此它返回 0)。

当新数据包出现时,缓冲区被重置,数据丢失。

解决方案是继续读取谷物数据,直到没有更多数据。如果这是在单独的线程中运行,即使 while(isRunning()) { ia >> v; / ... / } 就足够了。

于 2018-07-20T12:23:30.333 回答