Я использую boost.asio, и у меня есть простой сервер, которому необходимо обрабатывать несколько соединений. Прежде чем начать «подключенный» статус, мне нужно выполнить рукопожатие с клиентом в течение ограниченного периода времени. Я использую прикованные асинхронные операции для каждого шага рукопожатия, поскольку мне нужно использовать таймер и (насколько я знаю, я не могу этого сделать с синхронными чтениями и записью). Мне нужен способ заблокировать каждое соединение до тех пор, пока таймер тайм-тайма не закончится или рукопожатие не удастся, без блокировки сервера.asio - Дождитесь завершения операций async
Есть ли способ достичь этого?
UPDATE Некоторый код для уточнения вещи
Простой сервер
typedef boost::asio::ip::tcp::socket sock;
class server
{
public:
server() : _ios(), _acceptor(_ios)
{
boost::asio::ip::tcp::resolver resolver(_ios);
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), PORT);
_acceptor.open(endpoint.protocol());
_acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
_acceptor.bind(endpoint);
_acceptor.listen();
do_accept();
}
void run()
{
_ios.run();
}
private:
void do_accept()
{
auto socket = std::make_shared<TSock>(_ios);
_acceptor.async_accept(*socket, std::bind(&server::handle_accept,
this, socket, std::placeholders::_1));
}
void handle_accept(std::shared_ptr<sock> socket, const boost::system::error_code& ec)
{
auto connection = std::make_shared<CCon>();
if (connection->Accept(socket))
{
std::cout << "Connection accepted" << std::endl;
}
else
{
std::cout << "Connection not accepted" << std::endl;
}
do_accept();
}
boost::asio::io_service _ios;
boost::asio::ip::tcp::acceptor _acceptor;
std::set<std::shared_ptr<CCon>> _connections;
};
int32_t main(int32_t argc, char *argv[])
{
server s;
s.run();
}
connection-> Accept (гнездо) объяснил
bool CCon::Accept(<std::shared_ptr<sock>> tcpSocket)
{
// set handshake sequence
SendGreeting();
// I NEED TO WAIT HERE UNTIL connectionAccepted gets a value
if (connectionAccepted)
{
// Connection Accepted
return(true)
}
else
{
//Connection Rejected
return(false)
}
}
SendGreeting() содержит
boost::asio::async_write(*tcpSocket,
boost::asio::buffer(oBuff,bytesBuffered),
std::bind(&CCon::WaitForResp,
this, std::placeholders::_1));
Проблема в том, что WaitForResp никогда не вызывается. Он вызывается только после перезапуска io_service
(stop()
->reset()
->run()
) после установки нового обработчика, который не является решением.
Я думаю, что у меня что-то не хватает об Асио, и я был бы рад, если бы кто-нибудь мог мне помочь.
Мне нужно использовать асинхронные функции, потому что мне нужен таймер для рукопожатия, но мне также нужно подождать (заблокировать) часть моего кода для завершения рукопожатия или таймера до конца. – Bituki
Я пробовал использовать фьючерсы, но каким-то образом рукопожатие застревает в первом обработчике, пока 'future' не закончит свое время ожидания, а затем все рукопожатие (возможно, мне нужно, чтобы io_service работал в другом потоке?). Мне нужно некоторое время, чтобы упростить мой код и опубликовать его здесь, но я сделаю это, чтобы было ясно. – Bituki
@TechnikEmpire Я добавил код. Надеюсь, теперь все ясно. – Bituki