我有一个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)。我想知道是否有更直接,更优雅的方式来实现我想要的,或者整个设计只是有缺陷?
答案 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()调用,并且对已经完成的操作没有影响。
我不知道你从哪里得到这个错误的信息。我甚至都不知道这意味着什么。关机适用于套接字,而不是读取循环。