当我使用带有档案的boost :: async_read_until()时,它不会按照预期等待。由于我的客户端和服务器有点长,我将展示问题所在的方法。请帮我处理它们
//client
void doChat()
{
cout << "Enter message: ";
std::getline(cin, m_info.m_message);
m_info.m_id = 7;
{
std::stringstream ss;
boost::archive::binary_oarchive out(ss);
out & m_info;
m_string_stream = ss.str();
m_string_stream += '\n';
}
m_sock.async_write_some(boost::asio::buffer(m_string_stream),
[this](const boost::system::error_code& ec, std::size_t bytes)
{
if (ec == 0){
doChat();
}
});
因为我不知道如何直接发送存档对象,我使用字符串添加'\ n'假设服务器将读取直到'\ n'
//server
void doChatserver(std::shared_ptr<client> connection)
{
boost::asio::async_read_until(connection->m_sock, connection->m_stream_buffer, '\n',
[this, connection](const boost::system::error_code& ec, std::size_t bytes)
{
if (ec == 0)
{
{
boost::archive::binary_iarchive in_archive(connection->m_stream_buffer);
in_archive & connection->m_info;
}
doChatserver(connection); //--> problem when calling secondly
}
});
}
服务器从客户端读取后,作为回调它再次调用doChatserver(),但这次它不等待客户端的数据来,它只是崩溃! 那么您认为有什么问题?
答案 0 :(得分:1)
不是一个完整的答案,只是一些指示......
1)您应该反复调用async_write_some
,直到缓冲区为空。
请参阅async_write_some
文档中的注释:
写操作可能不会将所有数据传输到对等方。如果需要确保在异步操作完成之前写入所有数据,请考虑使用
async_write
函数。
因此,使用async_write
更容易,这可以保证缓冲区中的所有数据都被发送。
2)您应该将\n
从接收到的数据末尾删除,然后再将其传递给iarchive
,因为它不属于您的二进制存档。
3)如果您的二进制流包含字节0A
(\n
)怎么办? read_until会过早停止。考虑将数据的长度发送为整数(例如前4个字节),然后是数据本身。处理二进制数据时,请在\n
之前阅读。
发送功能:
接收功能:
读取前4个字节中指定的N个数据字节
示例:
boost::asio::read(socket, streambuf, boost::asio::transfer_exactly(n), ec);
4)使用调试器。打破并查看已读入connection->m_info
的内容。