我想在超时的情况下听boost::asio::ip::tcp::socket。为此,我使用了std::future::wait_for函数。下面是我的代码:
std::optional<boost::asio::ip::tcp::socket> server::listen()
{
boost::asio::ip::tcp::socket sock(io_service);
std::future<void> accept_status = acceptor.async_accept(
sock, boost::asio::use_future);
if (accept_status.wait_for(std::chrono::seconds(10)) == std::future_status::timeout)
{
// I hope there's no race-condition between
// accepting a connection and calling cancel
acceptor.cancel();
std::cerr << "Timeout" << std::endl;
return {};
}
std::cerr << "Accepted a connection" << std::endl;
return {std::move(sock)};
}但这不起作用:客户端可以连接,但我仍然超时。这意味着将来的对象和异步接受函数不会通信。我遗漏了什么?
我正在使用Boost版本的1.65。
对于Explorer_N,以下是一个完整的程序,它的工作方式与我预期的不同:
#include <boost/asio.hpp>
#include <boost/asio/use_future.hpp>
#include <chrono>
#include <future>
#include <iostream>
#include <thread>
using namespace std;
void server_listen() {
boost::asio::io_service io_service;
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 31132);
boost::asio::ip::tcp::acceptor acceptor(io_service, endpoint);
boost::asio::ip::tcp::socket socket(io_service);
std::future<void> accept_status = acceptor.async_accept(
socket, boost::asio::use_future);
while(true) {
if(accept_status.wait_for(std::chrono::seconds(10)) == std::future_status::timeout) {
acceptor.cancel();
std::cerr << "Timeout\n";
} else {
break;
}
}
// if I replace the lines starting from the async_accept call
// by just the following, everything works as expected
// acceptor.accept(socket);
std::cout << "Accepted a connection\n";
while(true) {
}
}
void client_connect() {
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::socket socket(io_service);
boost::asio::ip::tcp::endpoint endpoint(*resolver.resolve({"127.0.0.1", std::to_string(31132)}));
socket.connect(endpoint);
std::cout << "Connected to server\n";
while(true) {
}
}
int main() {
std::thread server(server_listen);
std::this_thread::sleep_for(std::chrono::seconds(2));
std::thread client(client_connect);
while(true) {
}
}由g++ -std=c++17 <program>.cpp -lpthread -lboost_system -o <program>编译。
我得到的输出是:
Connected to server
Timeout
Timeout
Timeout
Timeout
Timeout
Timeout
Timeout
Timeout
Timeout
Timeout
Timeout
Timeout
Timeout
...发布于 2019-06-24 16:36:47
要回答您的申请,请执行以下操作:
“未来的对象和异步接受函数无法通信”--这是不可能的。
“客户端能够连接,但我仍然获得超时。”,--您的客户端连接到侦听器是一个事件,而执行完成处理程序(设置promise)是另一个事件。
因此,连接可以在第9秒接受,而回调将安排在第11秒运行(例如)。
请记住,我们正在处理异步操作,因此对未来事件进行绝对预测是不正确的。
除此之外,
// I hope there's no race-condition between
// accepting a connection and calling cancel
acceptor.cancel();
std::cerr << "Timeout" << std::endl;
return {};acceptor.cancel();只是收集挂起的等待程序,并在ec设置为operation_aborted的情况下完成它们,如果处理程序已经到达完成事件队列,那么cancel()就是一个no-op
根据OP最近的编辑扩展我的答案:
using namespace std;
void server_listen() {
boost::asio::io_service io_service;
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 31132);
boost::asio::ip::tcp::acceptor acceptor(io_service, endpoint);
boost::asio::ip::tcp::socket socket(io_service);
auto work = make_work_guard(io_service);
using type= std::decay_t<decltype(work)>;
std::thread io([&](){io_service.run();});
std::future<void> accept_status = acceptor.async_accept(
socket, boost::asio::use_future);
if(accept_status.wait_for(std::chrono::seconds(10)) == std::future_status::timeout) {
acceptor.cancel();
std::cerr << "Timeout\n";
work.~type();
//break;
} else {
std::cout<<"future is ready\n";
work.~type();
// break;
}
io.join();
// if I replace the lines starting from the async_accept call
// by just the following, everything works as expected
// acceptor.accept(socket);
std::cout << "Accepted a connection\n";
}
void client_connect() {
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::socket socket(io_service);
boost::asio::ip::tcp::endpoint endpoint(*resolver.resolve({"127.0.0.1", std::to_string(31132)}));
socket.connect(endpoint);
std::cout << "Connected to server\n";
}
enter code here
int main() {
std::thread server(server_listen);
std::this_thread::sleep_for(std::chrono::seconds(2));
std::thread client(client_connect);
server.join(); client.join();
}在你的程序中有许多事情需要注意(避免不必要的自旋循环,不要忘记加入或分离std::thread,并确保在使用async*版本时调用io_service::run )
Start
Connected to server
future is ready
Accepted a connection
0
Finishhttps://stackoverflow.com/questions/56615760
复制相似问题