首页 > 解决方案 > Boost ASIO ip tcp iostream expires_from_now doesn't result in an error when connection fails

问题描述

We've come across a strange situation where our code reports that it has successfully opened a connection to an unreachable address. But it only happens when we actively reduce the time-out for a boost::asio::ip::tcp::iostream:

void Connect(std::string address, std::string port) {
    std::cout << "Waiting to connect: " << address << " at port " << port << "\n";
    boost::asio::ip::tcp::iostream s;

    s.expires_from_now(std::chrono::seconds(5));
    s.connect(address, port);

    if (!s) {
        std::cout << "Unable to connect: " << s.error().message() << "\n";
    } else {
        std::cout << "Success!" << "\n";
    }              
}

With the above code, connect("192.168.25.25", "1234"); will quickly report "Success!", even though the address is unreachable. If we remove the expires_from_now, then we instead get "Unable to connect: Connection timed out" after about 2 minutes - as we expect.

I would have expected that changing the timeout using expires_from_now would result in a time-out error state. We're using boost 1.68.

Is there any other way to find out that the time-out is reached, or perhaps more appropriately, whether the connection has been established?

标签: c++boostboost-asio

解决方案


The "Success" indication just means that nothing has gone wrong yet. It does not mean that the connect has succeeded. You chose not to wait to find out whether the connect succeeded or failed and to instead time out the wait for that result.

You cannot make a TCP connect operation fail early. The rules for the conditions under which a TCP connect attempt fails are part of the TCP specification and just setting a timeout won't change how long it takes the connection attempt to fail.

Querying for the remote_endpoint will however indicate an error condition if the connection has not been established, for example:

boost::system::error_code ec;
s.socket().remote_endpoint(ec);
if (ec)
{
    std::cout << "Unable to connect\n";
}

推荐阅读