Using boost::asio::ip::tcp::socket::cancel() and socket::close()
如果我使用关闭而不是取消,则存在一些问题。
close函数可以关闭套接字,并且通过返回boost::asio::error::operation_aborted错误来停止任何未完成的异步操作。
为什么应使用cancel而不是close?
我担心如果正在执行一些异步操作,cancel无法取消它,是吗?
像asio::ip::tcp::resolve::cancel一样,我多次尝试在调用async_resolve后取消resolve_handler,但是resolve_handler始终返回且没有boost::asio::error::operation_aborted错误。
我认为resolve_handler正在执行?
是?
cancel不会关闭套接字,因此如果要继续使用套接字对象,请使用cancel。特别是,如果异步处理程序方法中的代码引用了套接字的成员函数,则在确保当前执行的异步处理程序完成之前,您可能不想关闭套接字。
cancel不能保证与当前正在执行的异步处理程序有关,它只能保证(根据boost文档)在发生socket::cancel()调用的情况下,"此函数使所有未完成的异步连接,发送和接收操作立即完成"。 ,或者在resolver::cancel()调用的情况下,"此函数强制完成主机解析器上所有未完成的异步操作"。这种"完成"意味着boost将调用您的异步处理程序方法,它没有权限将任何取消逻辑注入到异步处理程序中(更不用说它不知道从一开始就知道该处理程序的实现)。
我建议将自己的逻辑添加到异步处理程序方法中,以处理socket / resolver / etc等情况。被取消。如果您正在调用cancel方法,则可能可以将此取消通知异步处理程序方法。
-
holtavolt是正确的,使用close()更可移植,但这完全取决于您要执行的操作。
-
谢谢您的帮助,是的,我创建了服务器对象来处理http请求并将这些对象放入std :: deque,一个任务即将来临,pop_front一个对象从双端队列开始工作,完成push_back该对象到双端队列时,出现错误 在连接过程中,发送或读取,我将关闭套接字,但是在连接和读取中,我设置20s超时,当连接超时时,我要取消回调函数handle_connect,在这个handle_connect_timeout或handle_read_timeout中,我不确定是哪个 一个可以使用,取消或关闭的按钮,但是现在,我认为对我来说最好的是关闭
如果要在不关闭套接字的情况下停止挂起的操作,则"取消"很有用。
请注意,Boost文档建议使用close以获得更大的可移植性(来自doc页面):
...
For portable cancellation, consider
using one of the following
alternatives:
-
Disable asio's I/O completion port
backend by defining
BOOST_ASIO_DISABLE_IOCP.
-
Use the
close() function to simultaneously
cancel the outstanding operations and
close the socket.
-
但是请注意,cancel()的备注也说明在Windows Vista,Windows Server 2008和更高版本上运行时,始终使用CancelIoEx函数。 此功能不存在上述问题。
-
谢谢你和山姆·米勒的帮助,我现在明白了,谢谢