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