强制异步套接字读取使用Boost.Asio

时间:2015-09-23 16:12:34

标签: c++ boost network-programming boost-asio

我有一个tcp::socket用于读写数据。在处理数据读取后,链接async_read_some()和处理程序on_data_read()再次调用async_read_some()组成了一个读取循环。循环传递相关的shared_ptr<tcp::socket>。如果on_data_read()调用error_code并且成功asio::error::eof,例如async_read_some(),则循环结束,在这种情况下async_write_some()不会被调用。

套接字上也可能存在异步写入,这是通过重复调用on_data_written()来完成的,直到写入所有数据。也就是说,async_write_some()的处理程序async_write_some()如果仅部分写入数据,则再次调用shared_ptr<tcp::socket>。相关的shared_ptr<tcp::socket>也会沿着调用链传递。

现在,我想以安全的方式关闭套接字。具体来说,我想强制异步读取以非成功错误代码提前完成以结束读取循环。如果没有挂起的写调用链,则唯一的tcp::socket(沿着读取循环传递的那个)会被管理shared_ptr<tcp::socket>关闭并销毁。如果存在挂起的写调用链,则会继续写入所有数据。在写调用链结束时,最后async_write_some()(沿着写调用链传递的那个)被破坏。这个过程是安全的,因为套接字在挂起写入后关闭,如果有的话。

问题是

  • 如何使用不成功的错误代码强制异步套接字读取完成?

我已查看linger选项。但由于我使用的是链接async_write()而不是单个on_data_written(),因此无法工作。因此,在调用cancel()时可以关闭套接字。 close()shutdown()也不会工作,因为它们不仅会中断读取循环,还会中断写入调用链。虽然async_read_some()只能应用于读取循环,但它仅会阻止将来的cancel()调用,并且对已经完成的操作没有影响。我已经找到了解决方案。也就是说,调用on_data_written(),但让cancel()忽略由pd.cut(pd.Series(np.arange(11)), bins = 5) 0 (-0.01, 2] 1 (-0.01, 2] 2 (-0.01, 2] 3 (2, 4] 4 (2, 4] 5 (4, 6] 6 (4, 6] 7 (6, 8] 8 (6, 8] 9 (8, 10] 10 (8, 10] dtype: category 引起的错误代码并继续写调用链。我对此解决方案不满意(请参阅备注部分here)。我想知道是否有更直接,更优雅的方式来实现我想要的,或者整个设计只是有缺陷?

3 个答案:

答案 0 :(得分:1)

在我看来,你已经很好地总结了它。

你不能真正做到比完全取消更好。事实上,你可以恢复任何取消的写作。

我认为没有更优雅的东西。我不会说设计存在缺陷,但你可能想要考虑不实际取消挂起的操作,而只是保留一个标志来指示“逻辑读取取消”是否正在等待并防止在这种情况下链接更多的读取

答案 1 :(得分:0)

当你使用shutdown ..例如.. socket.shutdown你是否使用了shutdown_both?

(boost :: asio :: ip :: tcp :: socket :: shutdown_both,ec)

shutdown_both选项。那应该处理读写闭包。

socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, errorcode);
if (errorcode)
{
    cerr << "socket.shutdown error: " << errorcode.message() << endl;
}

另外..如果你有io_service句柄。你可以调用io_service.stop()作为最后的手段来关闭所有的操作。

答案 2 :(得分:0)

关闭套接字以进行输入。这将导致所有挂起的读取遇到流的结束并相应地返回。

  

虽然shutdown()只能应用于读取循环,但它仅防止将来的async_read_some()调用,并且对已经完成的操作没有影响。

我不知道你从哪里得到这个错误的信息。我甚至都不知道这意味着什么。关机适用于套接字,而不是读取循环。