乐闻世界logo
搜索文章和话题

How to set a timeout on blocking sockets in boost asio?

1个答案

1

In Boost.Asio, there are multiple approaches to setting timeouts for blocking sockets, including utilizing system-specific options or leveraging Boost.Asio's built-in features. Below, I present two common methods to achieve this functionality:

Method 1: Using System-Specific Socket Options

For POSIX-compatible systems, you can employ setsockopt to configure socket timeouts, such as for sending and receiving operations:

cpp
#include <boost/asio.hpp> #include <iostream> #include <sys/socket.h> #include <chrono> void set_socket_timeout(boost::asio::ip::tcp::socket& socket, int timeout_seconds) { struct timeval timeout; timeout.tv_sec = timeout_seconds; timeout.tv_usec = 0; // Set receive timeout if (setsockopt(socket.native_handle(), SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) { std::cerr << "Failed to set receive timeout\n"; } // Set send timeout if (setsockopt(socket.native_handle(), SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) { std::cerr << "Failed to set send timeout\n"; } } int main() { boost::asio::io_context io_context; boost::asio::ip::tcp::socket socket(io_context); socket.connect(boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 12345)); set_socket_timeout(socket, 10); // Set 10-second timeout // Now you can use the socket for communication; if the operation is not completed within 10 seconds, it will time out }

Method 2: Using Boost.Asio's Asynchronous Operations with Timers

In Boost.Asio, combining asynchronous operations with timers effectively simulates a timeout mechanism. This approach offers the advantage of fully utilizing Boost.Asio's higher-level abstractions without dependency on platform-specific implementations:

cpp
#include <boost/asio.hpp> #include <iostream> void handle_timeout(const boost::system::error_code& error) { if (!error) { std::cout << "Operation timed out!\n"; } } int main() { boost::asio::io_context io_context; boost::asio::steady_timer timer(io_context, std::chrono::seconds(10)); timer.async_wait(&handle_timeout); boost::asio::ip::tcp::socket socket(io_context); socket.async_connect(boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 12345), [&](const boost::system::error_code& error) { if (!error) { timer.cancel(); // Cancel the timer if the connection succeeds } }); io_context.run(); // This code will block until the asynchronous operation completes or the timer triggers }

In this example, a 10-second timer is configured. If the asynchronous connection operation remains incomplete within this period, the timer's callback function will be invoked to handle the timeout scenario.

Both methods can be selected based on specific requirements and environments. The first method is lower-level and closer to system calls, while the second method leverages Boost.Asio's robust asynchronous processing capabilities. In practice, choose the appropriate method according to your framework and design needs.

2024年7月25日 23:11 回复

你的答案