title: Why boost asio async_read_some does not invoke the callback in a certain situation?
body: <p>I'm implementing a serial communication protocol to communicate with a external device over UART. I'm using boost asio for this. So far everything works fine, except very little cases. I found that it is possible that the reading from the socket does <em>"miss"</em> 1 byte in some cases. </p>
  
  <p>I checked the serial communication by using a UART sniffer to see the raw data which comes and goes over the socket. This being sad, I did see the full frame of bytes being transmitted over the socket. But in my application the last byte was just not received.</p>
  
  <p>I found that his byte is not <em>"lost"</em> it's somehow just <em>"stuck"</em> in the kernel buffer or something. Because on receiving the next frame I do get this <em>"missing"</em> byte in front of all the new bytes. This would not be a big problem if the frames would come in continuously. But the next frame is only sent by the device if the previous frame was acknowledged by the program.</p>
  
  <p>Here is the code of my write and handle receive method:</p>
  
  <pre><code>void serial::write(std::vector&lt;uint8_t&gt; message) {
      static boost::mutex mu;
      mu.lock();
      uint8_t cmd = message.at(3);
      //if its an ACK frame - just send it
      if ((message[3]&gt;&gt;4)==0xE) {
          // --- Write message to serial port --- //
          boost::asio::write(serial_,boost::asio::buffer(message));
          usleep(20000);
          mu.unlock();
          return;
      }
      //if its not an ACK frame write the frame and wait for an ACK!
      //create new promise for the request
      promise = new boost::promise&lt;deque&lt;uint8_t&gt;&gt;;
      boost::unique_future&lt;deque&lt;uint8_t&gt;&gt; future = promise-&gt;get_future();
      // --- Write message to serial port --- //
      boost::asio::write(serial_,boost::asio::buffer(message));
      usleep(20000);
      mu.unlock();
      //wait for ACK or timeout
      if     (future.wait_for(boost::chrono::milliseconds(100))==boost::future_status::timeout) {
          spdlog::get("logger")-&gt;trace("ACK timeout!");
          //delete pointer and set it to 0
          delete promise;
          promise=nullptr;
          //need to resend this frame
      }
      //delete pointer and set it to 0 after getting a message
      delete promise;
      promise=nullptr;
  }
  </code></pre>
  
  <p>handle receive:</p>
  
  <pre><code>void serial::handle_receive(const boost::system::error_code&amp; error, size_t bytes_transferred) {
       static deque&lt;uint8_t&gt; read_buffer;
       static boost::posix_time::ptime start =    boost::posix_time::microsec_clock::local_time( );
      if (boost::posix_time::microsec_clock::local_time( ) - start &gt; boost::posix_time::milliseconds(99)  &amp;&amp; !read_buffer.empty()) {
          spdlog::get("logger")-&gt;trace("time condition, clearing buffer!");
          read_buffer.clear();
      }
      start = boost::posix_time::microsec_clock::local_time( );
      if (!error) {
          //push all the recieved data into the deque
          for (unsigned int i = 0; i &lt; bytes_transferred; i++) {
              read_buffer.push_back((int)data_[i]);
          }
      }
      else if (error){
      spdlog::get("logger")-&gt;error("\n\n\n\nERROR: {0}\n\n\n\n", error);
      }
      while ( !read_buffer.empty()) {
          /*do here some checks if this could be a correct frame
         ...
         ...
         ...
         */
          //received frame is ready
          //check if it is an ACK frame
          //check if its a data frame and ACK it!
          //send an ACK if its a dataframe
          if (ACK)) {
              write(frame);
          }
          //give the data to the upper layer                  
          m_Receive_data_handler(receivedFrame,receivedFrame.size());
          }
      serial_.async_read_some(boost::asio::buffer(data_,max_length),
                          boost::bind(&amp;serial::handle_receive, this,
                                      boost::asio::placeholders::error,
                                      boost::asio::placeholders::bytes_transferred));
  
  }
  </code></pre>
  
  <p>Maybe somebody has an idea why it works on most cases, but fails just with the last byte of the frame?</p>
  
  <p>Thanks!</p>