助推ASIO async_connect收盘后的成功
boost asio async_connect success after close
单线程应用程序。
它不是每次都发生,只有在高负载 1.5 小时后才会发生。
- TCP::
- 套接字::async_connect TCP::
- 套接字::关闭(按deadline_timer)
- async_connect_handler 给出成功error_code(一百万次之一),但套接字被 (2) 关闭。 99.999% 的时间它给出 errno=125(ECANCELED)。
套接字实现或提升 asio 是否有可能以某种方式做到这一点:
- async_connect
- 异步成功发布到io_service
- 通过计时器关闭
- 异步成功由我处理,不受关闭的影响
现在通过在我的变量中保存状态来解决,忽略接受成功。
Linux 2.6 (fedora).提升 1.46.0
PS:我可能会有错误...但如果不是这样,可以顺利运行几天。
正如 Igor 在注释中提到的,完成处理程序已经排队。
此方案是执行操作和调用处理程序之间的时间分离的结果。 io_service::run()
、io_service::run_one()
、io_service::poll()
和io_service::poll_one()
的文档专门提到处理程序,而不是操作。 在该方案中,socket::async_connect()
操作和deadline_timer::async_wait()
操作在同一事件循环迭代中完成。 这会导致两个处理程序都以未指定的顺序添加到延迟调用的io_service
中。
请考虑以下强调方案的代码片段:
void handle_wait(const boost::system::error_code& error)
{
if (error) return;
socket_.close();
}
timer_.expires_from_now(boost::posix_time::seconds(30));
timer_.async_wait(&handle_wait);
socket_.async_connect(endpoint_, handle_connect);
boost::this_thread::sleep(boost::posix_time::seconds(60));
io_service_.run_one();
调用 io_service_.run_one()
时,socket::async_connect()
和deadline_timer::async_wait()
操作都可能已完成,从而导致 handle_wait
和 handle_connect
准备好以未指定的顺序从io_service
内部调用。 为了正确处理这个未指定的顺序,需要从handle_wait()
和handle_connect()
内部出现额外的逻辑来查询当前状态,并确定是否已调用其他处理程序,而不是仅仅依赖于操作的状态(error_code
)。
确定其他处理程序是否已调用的最简单方法是:
- 在
handle_connect()
中,通过is_open()
检查套接字是否仍然打开。 如果套接字仍处于打开状态,则表示尚未调用handle_timer()
。 向handle_timer()
指示handle_connect()
已运行的一种简洁方法是更新到期时间。 - 在
handle_timer()
中,检查过期时间是否已过。 如果这是真的,那么handle_connect()
还没有运行,所以关闭套接字。
生成的处理程序可能如下所示:
void handle_wait(const boost::system::error_code& error)
{
// On error, return early.
if (error) return;
// If the timer expires in the future, then connect handler must have
// first.
if (timer_.expires_at() > deadline_timer::traits_type::now()) return;
// Timeout has occurred, so close the socket.
socket_.close();
}
void handle_connect(const boost::system::error_code& error)
{
// The async_connect() function automatically opens the socket at the start
// of the asynchronous operation. If the socket is closed at this time then
// the timeout handler must have run first.
if (!socket_.is_open()) return;
// On error, return early.
if (error) return;
// Otherwise, a connection has been established. Update the timer state
// so that the timeout handler does not close the socket.
timer_.expires_at(boost::posix_time::pos_infin);
}
Boost.Asio 提供了一些处理超时的示例。
我接受twsansbury的回答,只是想添加更多信息。
关于关机():
void async_recv_handler( boost::system::error_code ec_recv, std::size_t count )
{
if ( !m_socket.is_open() )
return; // first time don't trust to ec_recv
if ( ec_recv )
{
// oops, we have error
// log
// close
return;
}
// seems that we are just fine, no error in ec_recv, we can gracefully shutdown the connection
// but shutdown may fail! this check is working for me
boost::system::error_code ec_shutdown;
// second time don't trusting to ec_recv
m_socket.shutdown( t, ec_shutdown );
if ( !ec_shutdown )
return;
// this error code is expected
if ( ec_shutdown == boost::asio::error::not_connected )
return;
// other error codes are unexpected for me
// log << ec_shutdown.message()
throw boost::system::system_error(ec_shutdown);
}
- cmake在我的项目中所需的所有静态库都不成功
- 尽管测试成功,CppUnit测试核心仍被丢弃.为什么
- 如何让LLDB在成功时退出,在失败时等待
- 有没有办法知道Tracer是否成功地完全连接到了jaegerclientcpp中的jaeger后端服务器
- CMake WxWidgets项目成功地在Linux上构建,但没有在Windows上构建
- 为什么 std::绑定错误参数可以成功?
- Clion显示错误,但可以使用Cmake成功构建代码
- 代码使用向量成功运行,但使用数组显示错误
- WinSock2:connect() 提供"连接被拒绝"
- 如何检查cURL是否成功登录?c ++
- 如何使用connect将qml按钮与同一类的cpp函数连接起来
- 在 QTextEdit 中使用指针或在 Qt-Creator 上使用 connect()
- 为什么 WinInet 在通过 FQDN 连接时无法通过协商自动进行身份验证,但如果通过 IP 连接则成功?
- C++为什么我的编译器成功了,但我的计算机给出了调试错误?
- 未知的 GCC 链接器错误,但已成功构建
- 我的 SonarQube C++扫描成功,但结果仅标记重复项,而没有标记其他标记的位置
- 为什么 LoadLibrary 失败,而 LoadLibraryA 成功加载 DLL?
- 生成成功,但不会给出正确的输出
- 默认/样板代码在Visual Studio 2017中给我错误.E1574.虚幻.但构建成功了
- 插座:为什么Accept()挂起,但是Connect()成功