0

I'm completely new to c++ and boost::asio. But in my work, as much as I would not like, I had to resort to using boost::asio. And i have a huge problem.

I do not know why, but every time I try to use boost:: asio (as a client) to connect to the server with wrong server's ip address, I get into an infinite blocking loop.

The simplest example:

int main(int argc, char* argv[]){

namespace ba = boost::asio;
using ba::ip::tcp;

ba::io_service service;
tcp::socket s(service);

if (argc<3)
    return 255;

try {
    auto it = tcp::resolver(service).resolve({argv[1], argv[2]});
    s.connect(*it); // first resolved value

    std::cout << "Connected " << s.local_endpoint() << " -> " << s.remote_endpoint() << "\n";

    // demo write
    ba::write(s, ba::buffer("hello world\n"));
} catch (const boost::system::system_error& e) {
    std::cout << "ERROR:" << e.what() << "\n";
}}

The problem occurs when I enter an incorrect address and port, for example: "1.2.3.4, 1001" "12.13.14.15, 4441" etc.

When the execution comes to

s.connect(*it); // first resolved value

The whole program goes into a block and never returns.

Initially, I gave a simpler example, because in fact, the problem occurred in my more complex program, but in a slightly different place.

In a more complex version, the program goes into a block on

io_context.run();

There's code:

boost::asio::io_context io_context;
    boost::asio::ip::tcp::resolver resolver(io_context);
    boost::asio::ip::tcp::resolver::results_type endpoints;


    std::string address = ui->lineEdit_primaryServerAddress->text().toStdString();
    endpoints = resolver.resolve(address, INET_SERVICE);

    boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
    ctx.load_verify_file(SSL_CERT);

    rb_baseClient c(io_context, ctx, endpoints);
    c.set_request(CLNT_MSG_WHO_ARE_YOU);

    try
    {
        boost::system::error_code _ec2;
        io_context.run();
    }

    catch (std::exception& e)
    {
        io_context.stop();
        std::cerr << e.what() << std::endl;
        ui->label_primaryServerHostname->setStyleSheet("color: darkred");
        this->pServerIsAlive = false;
        emit pServerStatusChanged(false);
    }

    std::string reply=c.get_reply();

What does the program do? My program is a client that must establish a connection with the main server, receive a predetermined response from it, and if the response is satisfactory, the user can continue working with the client.

Here is some code from inside the client class:

try
{
    _socket.set_verify_mode(boost::asio::ssl::verify_peer);
    _socket.set_verify_callback(
                boost::bind(&rb_baseClient::verify_certificate, this, _1, _2));

    boost::asio::async_connect(_socket.lowest_layer(), _endpoints,
                               boost::bind(&rb_baseClient::handle_connect, this,
                                           boost::asio::placeholders::error));
}
catch (std::exception& e)
{
    cerr << "rb_baseClient::connect: " << e.what();
    strcpy(_reply, SERVER_CONNECTION_FAILED);
}

I tried to use deadline timers for asynchronous connection, but nothing helped. It also didn't help to catch exceptions, because after entering io_context.run, the program stops showing signs of life at all. In the official documentation boost.org I also didn't find anything that could fix the situation. How can I solve this problem?

I am using the ubuntu 20.04 operating system, boost 1.77

It's a funny fact, but the program does not block only on my boss's computer. My boss ' computer has an identical configuration. I also tried to test this code on other machines with Debian, Windows and macOS, but it turned out to be useless. The result is the same.

How can I solve this problem? Thank you in advance

0 Answers0