Note that there are some explanatory texts on larger screens.

plurals
  1. POTimeouts on read and writes
    text
    copied!<p>I have been searching for a way to cancel a Boost ASIO read or write operation if it takes over a certain amount of time. My server is sending out HTTP requests, and reading results from those requests, so I originally had coded it as a synchronous read/write, and if it took so long, I would just carry on and ignore the results when they came back. This caused a problem if a server went down, my server would open to many sockets, and would crash. So I decided that I wanted to cancel the read/write if there was too long of a delay, but apparently synchronous read/writes are not able to be canceled without destroying the thread they are running in, which I do not want to do. So I found a post about how to mimic a synchronous read/write with asynchronous calls and cancel a call on time out. <a href="http://lists.boost.org/Archives/boost/2007/04/120339.php" rel="nofollow">This</a> is the post that I followed. I know this post is fairly old, so I am not sure if function calls have change since that version and the one I am working with(1.48), but this doesn't seem to be working quite right. Here is my code</p> <pre><code>bool connection::query_rtb(const std::string &amp;request_information, std::string &amp;reply_information) { try { boost::optional&lt;boost::system::error_code&gt; timer1_result, timer2_result, write_result, read_result; boost::array&lt;char,8192&gt; buf; buf.assign(0); boost::asio::deadline_timer dt(io_service_); dt.expires_from_now(boost::posix_time::milliseconds(100)); dt.async_wait(boost::bind(&amp;connection::set_result, this, &amp;timer1_result, _1, "timer1")); boost::asio::async_write(socket_, boost::asio::buffer(request_information, request_information.size()), boost::bind(&amp;connection::set_result, this, &amp;write_result, _1, "write")); io_service_.reset(); while(io_service_.run_one()) { if(write_result) { dt.cancel(); } else if(timer1_result) { socket_.cancel(); } } boost::asio::deadline_timer dt2(io_service_); dt2.expires_from_now(boost::posix_time::milliseconds(3000)); dt2.async_wait(boost::bind(&amp;connection::set_result, this, &amp;timer2_result, _1, "timer2")); boost::asio::async_read(socket_, boost::asio::buffer(buf), boost::bind(&amp;connection::set_result, this, &amp;read_result, _1, "read")); //socket_.async_receive(boost::asio::buffer(buf), boost::bind(&amp;connection::set_result, this, &amp;read_result, _1, "read")); io_service_.reset(); while(io_service_.run_one()) { if(read_result) { dt2.cancel(); } if(timer2_result) { socket_.cancel(); } } reply_information = buf.data(); std::cout &lt;&lt; reply_information &lt;&lt; std::endl; return true; }catch(std::exception&amp; e) { std::cerr &lt;&lt; e.what() &lt;&lt; std::endl; } } void persistent_connection::set_result(boost::optional&lt;boost::system::error_code&gt; *a, boost::system::error_code ec, std::string t) { std::cout &lt;&lt; t &lt;&lt; std::endl; a-&gt;reset(ec); } </code></pre> <p>I was wondering if anyone see anything wrong with this code, or has any ideas on why it is not working. Currently the write seems to be fine, however the will not read until after the dt2 is done with it's timer. Please let me know if you need any more information, I will be glad to provide some.</p> <p>Edit:</p> <p>Seems like I got it working testing something I thought I previously tested. Using <code>async_receive</code> instead of <code>async_read</code> seems to have fixed whatever problem I was having. Any clue why this would cause I problem? I want to know if there is a problem with my logic or if that is how is <code>async_read</code> will usually act.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload