Asio problems with async_read
Hi I have a funciton where we I am using boost::asio to read from the serial port of my computer. I have started out with an implementation which uses read, and I am now trying to convert it to async_read because I want a time out. When I am trying to use the async_read version, I get timeouts after I have read one or two charterers, even though I know there are more charterers to be read on the wire. Here is the code: void set_result( boost::optional<boost::system::error_code> * a, boost::system::error_code b ) { a->reset( b ); } std::vector<uint8_t> receive(boost::asio::io_service & io, boost::asio::serial_port & cctalk_port){ #if 0 boost::optional<boost::system::error_code> timer_result; boost::optional<boost::system::error_code> read_result; boost::asio::deadline_timer timer( io ); timer.expires_from_now( boost::posix_time::milliseconds(5000) ); timer.async_wait( boost::bind(&set_result, &timer_result, _1) ); boost::asio::streambuf result; boost::asio::async_read( cctalk_port, result, boost::asio::transfer_at_least(1), boost::bind( &set_result, &read_result, _1 )); while(1) { io.poll_one(); if ( read_result ) { timer.cancel(); std::vector<uint8_t> res(boost::asio::buffer_cast<const uint8_t * >(result.data()), boost::asio::buffer_cast<const uint8_t *
(result.data()) + result.size() );
return res; } else if ( timer_result ) { throw runtime_error("timeout"); } } throw runtime_error("Should not happend"); #else uint8_t c; boost::asio::read(cctalk_port, boost::asio::buffer(&c, 1)); std::vector<uint8_t> res; res.push_back(c); return res; #endif }
Hi Here is how I call the function I have splitted it in two like this, because the protocol specifies a timeout pr. character and not pr. message std::vector<uint8_t> receive(boost::asio::io_service & io, boost::asio::serial_port & cctalk_port, size_t size){ std::vector<uint8_t> v; size_t i = 0; while( i < size ) { std::vector<uint8_t> _v = receive(io, cctalk_port); copy(_v.begin(), _v.end(), std::back_inserter(v)); i += _v.size(); cout << "Received: " << v.size() << "/" << size << endl; } return v; } On Mon, Aug 8, 2011 at 2:32 PM, Igor R <boost.lists@gmail.com> wrote:
boost::asio::async_read( cctalk_port, result, boost::asio::transfer_at_least(1), boost::bind( &set_result, &read_result, _1 ));
The above call promises you to read 1 byte. After it completes, where do you start another one? _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Here is how I call the function
I have splitted it in two like this, because the protocol specifies a timeout pr. character and not pr. message
std::vector<uint8_t> receive(boost::asio::io_service & io, boost::asio::serial_port & cctalk_port, size_t size){ std::vector<uint8_t> v; size_t i = 0;
while( i < size ) { std::vector<uint8_t> _v = receive(io, cctalk_port); copy(_v.begin(), _v.end(), std::back_inserter(v)); i += _v.size(); cout << "Received: " << v.size() << "/" << size << endl; }
return v; }
Note that if poll_one() exits due to "out of work", you have to call io_service::reset() http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/reference/io_servic...
Hi
Note that if poll_one() exits due to "out of work", you have to call io_service::reset()
I am not sure that this is my problem... I have added some more debug code prints: void set_result( boost::optional<boost::system::error_code> * a, boost::system::error_code b ) { a->reset( b ); } void receive(boost::asio::io_service & io, boost::asio::serial_port & cctalk_port, boost::asio::streambuf & result){ boost::optional<boost::system::error_code> timer_result; boost::optional<boost::system::error_code> read_result; boost::asio::deadline_timer timer( io ); LOG(INFO) << "Timer at 5000ms starts here"; timer.expires_from_now( boost::posix_time::milliseconds(5000) ); timer.async_wait( boost::bind(&set_result, &timer_result, _1) ); LOG(INFO) << "Async read starts here"; boost::asio::async_read( cctalk_port, result, boost::asio::transfer_at_least(1), boost::bind( &set_result, &read_result, _1 )); boost::system::error_code ec; while(1) { io.poll_one(ec); if( ec != 0 || read_result != 0 || timer_result != 0) LOG(INFO) << "Error code: " << ec << " read_result: " << read_result << " timer_result: " << timer_result; if ( read_result ) { timer.cancel(); LOG(INFO) << "Result ready"; return; } else if ( timer_result ) { LOG(INFO) << "Timeout"; throw runtime_error("timeout"); } } LOG(INFO) << "Not suppose to happen"; } When this function is called twice I got the following output: I0808 16:27:31.632927 31531 ccTalkScan.cxx:92] Timer at 5000ms starts here I0808 16:27:31.632993 31531 ccTalkScan.cxx:96] Async read starts here I0808 16:27:31.633018 31531 ccTalkScan.cxx:108] Error code: system:0 read_result: 1 timer_result: 0 I0808 16:27:31.633026 31531 ccTalkScan.cxx:112] Result ready I0808 16:27:31.633080 31531 ccTalkScan.cxx:92] Timer at 5000ms starts here I0808 16:27:31.633095 31531 ccTalkScan.cxx:96] Async read starts here I0808 16:27:31.633112 31531 ccTalkScan.cxx:108] Error code: system:0 read_result: 0 timer_result: 1 I0808 16:27:31.633121 31531 ccTalkScan.cxx:116] Timeout So, what I do not understand is why does the timeout event occur after 32 ms, when I have specified 5000? -- Allan W. Nielsen
participants (2)
-
Allan Nielsen
-
Igor R