как запустить опрос с таймаутом в сети Ц - PullRequest
0 голосов
/ 03 апреля 2019

У меня есть сокет ip :: tcp :: acceptor, я хочу опрашивать и проверять, готов ли он к принятию, а не блокировать и принимать вызов, но я бы хотел сделать это с таймаутом.

net::io_context ioc;
auto endpoint = ip::basic_endpoint<ip::tcp> 
 (ip::address_v4::loopback(), port_num);
auto socket = ip::tcp::acceptor(ioc, ip::tcp::v4());
std::error_code ec;
socket.bind(endpoint);
socket.listen();
auto ct = ioc.poll_one();
auto tcp_socket = socket.accept();

1 Ответ

1 голос
/ 06 апреля 2019

Для начала вызов poll_one ничего не делает .. нет асинхронной работы, ожидающей немедленного возврата.

Приведенный выше код будет «блокировать» вызов «accept» до тех пор, пока не будет принят новый сокет.

Нет способа (о чем я знаю) сделать тайм-аут в этой ситуации. Вы должны использовать асинхронные методы на этом этапе, если вы хотите контролировать время ожидания.

например. (используя boost asio)

#include <boost/asio.hpp>
#include <iostream>

using namespace std::chrono_literals;

int main()
{
    const unsigned short port_num = 100;
    boost::asio::io_context ioc;
    auto endpoint = boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>(boost::asio::ip::address_v4::loopback(), port_num);
    auto acceptor = boost::asio::ip::tcp::acceptor(ioc, boost::asio::ip::tcp::v4());
    auto timer = boost::asio::system_timer(ioc);

    acceptor.bind(endpoint);
    acceptor.listen();

    timer.expires_from_now(10s);
    timer.async_wait([&acceptor](auto const& ec)
        {
            if (!ec)
            {
                std::cout << "timed out";
                boost::system::error_code cec;
                acceptor.cancel(cec);
            }
        });

    acceptor.async_accept([&timer](auto const& ec, auto tcp_socket)
        {
            if(!ec)
            {
                std::cout << "socket accepted";
                boost::system::error_code cec;
                timer.cancel(cec);
                tcp_socket.shutdown(boost::asio::socket_base::shutdown_both);
            }
        });

    ioc.run();
    return EXIT_SUCCESS;
}
...