关于ssl::stream::async_shutdown的正确调用方式及异步操作共存疑问
关于ssl::stream::async_shutdown的正确调用方式及异步操作共存疑问
嘿,这个问题问到点子上了——在ASIO的SSL异步编程里,操作时序绝对是最容易踩坑的点之一,我结合自己实际项目里的经验和官方文档的细节给你梳理清楚:
1. 能不能在有未完成的async_read_some/async_write时调用ssl::stream::async_shutdown?
结论是可以调用,ASIO并没有禁止这种操作,但你必须清楚后续的行为,并且做好对应的错误处理逻辑。
2. 调用后正在进行的异步操作会发生什么?
- 已经提交的异步读写操作不会被直接中断:ASIO的异步IO操作一旦提交到执行器,除非你主动调用
cancel()来取消,否则会继续尝试完成。 - 不同操作的后续表现有差异:
- 对于
async_write_some:大概率会正常完成数据发送,因为SSL协议层会优先处理已经在发送队列里的应用数据,再执行关闭握手流程。完成后对应的write handler会被调用,返回成功状态。 - 对于
async_read_some:很可能会因为SSL连接进入关闭流程而触发错误,比如返回ssl::error::stream_truncated或者asio::error::eof这类错误码。这时候你需要在read handler里判断错误类型,如果是因为shutdown导致的,就不需要做额外的错误处理,直接继续推进shutdown的后续流程即可。
- 对于
3. 更稳妥的实践建议
虽然允许在未完成读写时发起shutdown,但更推荐先等待所有未完成的异步操作完成(或主动取消),再调用async_shutdown:
- 这样可以让代码逻辑更清晰,避免在多个handler里处理交叉的错误状态。比如你可以维护一个简单的计数器,每发起一个异步操作就+1,handler执行完成后-1,当计数器归0时再触发shutdown。
- 如果某些异步操作长时间未完成,你也可以主动调用
ssl::stream::cancel()来取消所有未完成的异步IO操作,待cancel的handler触发后再发起shutdown。
最后要提醒一句:不管async_shutdown是成功还是失败,在它的handler里一定要记得关闭底层的socket,避免出现资源泄漏的问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

