提升io_service不会重置
boost io_service doesn't reset
>我正在尝试为升压套接字实现一个ConnectWithTimeout函数。所以我使用我在这里找到的例子之一。这在第一次尝试中非常有效,但 io_service.run_one(( 会立即返回超时或取消错误。
这是我的代码
using NetStatus = boost::system::error_code;
NetStatus handleWait(const NetStatus& error)
{
return boost::asio::error::timed_out;
}
NetStatus handleConnect(const NetStatus& 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 (!m_socket.is_open())
return boost::asio::error::timed_out;
// Otherwise, a connection has been established. Update the timer state
// so that the timeout handler does not close the socket.
m_connectionTimeoutTimer.cancel();
return error;
}
void connectWithTimeout(boost::asio::ip::tcp::endpoint& endpoint, NetStatus& e)
{
// Stop last time's waiting objects
m_socket.cancel()
m_connectionTimeoutTimer.cancel();
m_ioService.stop();
m_ioService.reset();
// Set-up new objects to wait
m_connectionTimeoutTimer.expires_from_now(boost::posix_time::seconds(5));
m_connectionTimeoutTimer.async_wait([this, &e](const NetStatus& error) { e = handleWait(error); } );
m_socket.async_connect(endpoint, [this, &e](const NetStatus& error) { e = handleConnect(error); } );
// Block until one of them is done
m_ioService.run_one(e);
}
boost::asio::ip::tcp::socket m_socket;
boost::asio::deadline_timer m_connectionTimeoutTimer;
在循环中运行时,我看到的结果是: 超时(按预期在 5 秒后( 取消(立即( 超时(立即( 取消(立即( 超时(立即( 取消(立即( 超时(立即( ...
任何人都可以帮助发现我做错了什么吗?
您是否正在关闭每个循环之间的套接字?您在同一个m_socket
实例上调用async_connect
,但我没有看到套接字关闭的位置。您可能在尝试连接已打开的套接字时遇到错误。尝试m_socket.close()
而不是m_socket.cancel()
。
好的,所以我找到了答案,似乎将处理程序从io_service中取出的唯一方法是使用 run 或 run_one、reset 等调用它。 是我得到的最终代码,如果有人感兴趣:
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/timer/timer.hpp>
std::string bindToIp;
std::string ip;
int port;
auto tcpConnectionTrials = 5ul;
using NetStatus = boost::system::error_code;
boost::asio::io_service m_ioService;
boost::asio::ip::tcp::socket m_socket(m_ioService);
boost::asio::deadline_timer connectionTimeoutTimer(m_ioService);
bool isTimedOut = false;
void handleWait(boost::asio::ip::tcp::socket& socket, const NetStatus& error)
{
if (error != boost::asio::error::operation_aborted)
{
isTimedOut = true;
socket.cancel();
socket.close();
}
}
void handleConnect(boost::asio::ip::tcp::socket& socket, const NetStatus& error)
{
if (error != boost::asio::error::operation_aborted)
{
// 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())
{
connectionTimeoutTimer.cancel();
}
}
}
void connectWithTimeout(boost::asio::ip::tcp::socket& socket,
boost::asio::deadline_timer& connectionTimeoutTimer,
boost::asio::io_service& m_ioService,
boost::asio::ip::tcp::endpoint& endpoint,
NetStatus& e)
{
isTimedOut = false;
// Set-up new objects to wait
connectionTimeoutTimer.expires_from_now(boost::posix_time::seconds(5));
connectionTimeoutTimer.async_wait([&socket](const NetStatus& error) { handleWait(socket, error); } );
socket.async_connect(endpoint, [&socket, &e](const NetStatus& error) { e = error; handleConnect(socket, error); } );
// Block until one of them is done
m_ioService.run();
if (isTimedOut)
{
e = boost::asio::error::timed_out;
}
m_ioService.reset();
}
NetStatus connect()
{
NetStatus e;
boost::asio::ip::tcp::endpoint remoteEndpoint(boost::asio::ip::address_v4::from_string(ip.c_str()), port);
boost::asio::ip::tcp::endpoint localEndpoint(boost::asio::ip::address_v4::from_string(bindToIp.c_str()), 0);
std::cout << "Open socket: " << std::endl;
if (m_socket.open(boost::asio::ip::tcp::v4(), e))
{
std::cout << "Socket " << ": could not open!!!" << std::endl;
return e;
}
m_socket.set_option(boost::asio::socket_base::reuse_address(true));
m_socket.set_option(boost::asio::ip::tcp::no_delay(true));
std::cout << " binds to " << bindToIp << std::endl;
m_socket.bind(localEndpoint);
std::cout << " connect to " << ip << std::endl;
connectWithTimeout(m_socket, connectionTimeoutTimer, m_ioService, remoteEndpoint, e);
return e;
}
int main(int argc, char *argv[])
{
bindToIp = argv[1];
ip = argv[2];
port = atoi(argv[3]);
for(int i =0; i < 10; i++)
{
auto e = connect();
if (!e)
{
std::cout << "GOOD!" << std::endl;
break;
}
else
{
std::cout << "Failed: " << e.message() << std::endl;
}
m_socket.close();
}
std::cout << "DONE!" << std::endl;
return 0;
}
相关文章:
- Seg Fault Issue C++ (file IO / getline)
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 为什么在读取文件大小时文件IO速度会发生变化
- Agora.io 虚幻引擎插件构建错误
- 不将数据 socket.io c++(客户端)发送到 nodejs(服务器)socket.io
- ASIO signal_set多个 IO 线程不可靠,具体取决于代码顺序?
- 通过 Tor 服务C++ socket.io 客户端
- 如何使用可视化代码和平台IO将环境变量注入CPP文件?
- 如何读取 google::p rotobuf::io::CodedOutputStream::WriteVarint32
- Conan.io 在编译步骤中或已经在签出时
- C++中真正的异步文件 IO
- 在C++中返回 IO 对象的目的是什么?
- 使用 Broadcast 发出的从节点服务器发送的数据不能被 C++ 套接字 IO 客户端读取
- C++网络 IO、文件处理和网络故障
- Xcode OSX上的C++构建失败,出现多个错误文件IO..不可用:在macOS 10.15中引入
- Android Studio-在现有的旧项目中启用本机C++调试(card.io Android Source)
- 如何检测函数是否执行IO操作
- 如何键入用于const对象的自定义io操纵器
- libevent是否允许在不同的线程中运行timer/io的回调
- IO服务重新启动后,Boost最后期限计时器持续触发