The architecture of our project network was created in a separate stream. To avoid problems, it was decided to rewrite it asio with lock mode. This is done, but now it is time to set a timeout for sockets. During this process, I ran into a problem when the asio recvmsg call did not respond to SO_RCVTIMEO timeout.
He hangs in
/boost/asio/detail/impl/socket_ops.ipp:784 (versions 1_59):
signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec);
This is how I set the timeout (successfully):
auto socket = tcp::socket(io_service_); boost::system::error_code ec; tcp::resolver resolver(io_service_); tcp::resolver::query query(req_.host, boost::lexical_cast<std::string>(req_.port)); auto endpoint_iterator = resolver.resolve(query); boost::asio::connect(socket, endpoint_iterator, ec); if (ec) { return ec.value(); } struct timeval tv; tv.tv_sec = req_.timeout / 1000; tv.tv_usec = 0; std::cout << "Setting timeout for: " << tv.tv_sec << std::endl; if (setsockopt(socket.native_handle(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) { std::cout << "Error while setting rcv timeout" << std::endl; } if (setsockopt(socket.native_handle(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) { std::cout << "Error while setting snd timeout" << std::endl; }
No error is written in my output when setting the socket timeouts, so I believe that this operation was successful, however, the read_until call never ends due to the recvmsg call. Why recvmsg ignore socket timeout? And how can I set a timeout for asio code blocking mode? I read this one to do this.
My read code in which read_until waits forever:
boost::asio::streambuf response; std::istream response_stream(&response); boost::system::error_code ec; boost::asio::read_until(socket, response, "\r\n", ec);
I am using archlinux, kernel version 4.2.5-1. The method by which I test the timeout opens the listening server with nc :
nc -l -p 5000
and connect to it using the code above.
UPDATE:
It seems that I have only options to make reading asynchronous or to use select in native_socket. So, if no solution is provided here, I use select .