title: Why does boost::asio::async_read fail to read the requested number of bytes?
body: <p>I've got a problem where <code>boost::asio::async_read</code> fails on the second call, in a strange way:</p>
  
  <pre><code>std::atomic&lt;error_code&gt; ec(asio::error::would_block);
  size_t len = 0;
  
  // 1st call
  asio::async_read(socket,
                   asio::buffer(buffer+X),
                   asio::transfer_exactly(512-X),
                   [&amp;] (error_code const&amp; err, size_t bytesTransferred)
                   {
                       len = bytesTransferred;
                       ec.store(err, std::memory_order_release);
                   }
  );
  /////// ... wait for read to complete ...
  // 2nd call
  asio::async_read(socket,
                   asio::buffer(buffer),
                   asio::transfer_exactly(512),
                   [&amp;] (error_code const&amp; err, size_t bytesTransferred)
                   {
                       len = bytesTransferred;
                       ec.store(err, std::memory_order_release);
                   }
  );
  </code></pre>
  
  <p>The constant <code>X</code> is because I have some data already that I got in another way,
  so the first read is smaller. Say X=364, then <code>bytesTransferred</code> will be 148 the first time around. My problem however is that the second read <strong>again</strong> returns 148 bytes, even though <strong>that</strong> read was for 512 bytes exactly.</p>
  
  <p>I'm baffled. The second call doesn't have an error condition (I checked <code>err</code>). <code>bytesTransferred</code> is an argument passed by <code>aync_read</code> to me, and it's 148 bytes twice. The first time, it matches the <code>asio::transfer_exactly(148)</code> higher up on the stack .The second time the callstack clearly has a <code>asio::transfer_exactly(512)</code>. What is going on here? </p>
  
  <p>It's particular to that second call, though, The third call again reads 512 bytes, but also gets 512 bytes. </p>
  
  <p>[MCVE]</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;atomic&gt;
  
  #include &lt;boost/asio/buffer.hpp&gt;
  #include &lt;boost/asio/ip/tcp.hpp&gt;
  #include &lt;boost/asio/write.hpp&gt;
  #include &lt;boost/asio/read_until.hpp&gt;
  #include &lt;boost/asio/read.hpp&gt;
  
  // Minimal example, code that works has error checking removed. Class members turned itno globals etc.
  namespace {
      boost::asio::io_service io_service;
      boost::asio::ip::tcp::resolver resolver(io_service);
      boost::asio::ip::tcp::socket sock(io_service);
      std::vector&lt;char&gt; data(512);
      boost::asio::mutable_buffers_1 buffer(&amp;data[0], data.size());
      unsigned read_counter = 1;
      std::atomic&lt;unsigned&gt; read_timeout;
  }
  
  boost::system::error_code openSocket(const std::string &amp;server,
                                       const std::string &amp;port)
  {
      boost::system::error_code error = boost::asio::error::host_not_found;
      using boost::asio::ip::tcp;
      tcp::resolver::query query(server, port);
      tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
      tcp::resolver::iterator end;
  
      while (error &amp;&amp; endpoint_iterator != end)
      {
          sock.close();
          sock.connect(*endpoint_iterator++, error);
      }
      if (error)
      {
          std::cerr &lt;&lt; "No route\n";
          sock.close(); // Would be wrong to leave it open.
      }
      return error;
  }
  
  int read(size_t bytesNeeded)
  {
      size_t buffer_len = boost::asio::buffer_size(buffer);
      size_t byteShift = buffer_len - bytesNeeded; // Read into back of buffer.
  
      const int timeoutSeconds = 10;
      boost::asio::deadline_timer deadline(io_service);
      deadline.expires_from_now(boost::posix_time::seconds(timeoutSeconds)); // This will reset any outstanding timer
      read_counter += 2; // If we'd use +1, after 4 billion cycles it would reset to 0
      read_timeout.store(0, std::memory_order_release); // 0 = no timeout.
      unsigned read_counter_copy = read_counter; // Can't capture global.
      deadline.async_wait([read_counter_copy](boost::system::error_code const&amp;) {
          // read_timeout is very intentionally captured by value - timeout events are numbered
          read_timeout.store(read_counter_copy, std::memory_order_release); }
      );
  
      // Start reading "asynchronously", wait for completion or timeout:
      std::atomic&lt;boost::system::error_code&gt; ec(boost::asio::error::would_block);
      size_t len = 0;
  
      boost::asio::async_read(sock, boost::asio::buffer(buffer + byteShift), boost::asio::transfer_exactly(bytesNeeded),
          [&amp;, bytesNeeded](boost::system::error_code const&amp; err, size_t bytesTransferred)
          {
              if (bytesTransferred != bytesNeeded) {
                  std::cout &lt;&lt; bytesTransferred &lt;&lt; " , " &lt;&lt; err.message() &lt;&lt; std::endl;
              }
              len = bytesTransferred;
              ec.store(err, std::memory_order_release);
          }
      );
  
      do {
          io_service.run_one();
      } while (read_timeout.load(std::memory_order_acquire) != read_counter &amp;&amp; // Continue if the **last** read didn't time out
          (ec.load(std::memory_order_acquire) == boost::asio::error::would_block) &amp;&amp; // ec.store() not called,
          !io_service.stopped()); // and program still running.
  
      deadline.cancel(); // This will set read_timeout, if it wasn't set yet. But we ignore it from now on.
  
      if (ec.load(std::memory_order_acquire))
      {
          std::cerr &lt;&lt; "oops\n"; // Real error handling omitted.
          throw std::runtime_error("");
      }
      else if (read_timeout == read_counter)
      {
          std::cerr &lt;&lt; "timeout\n";
      }
      else if (len != bytesNeeded)
      {
          // This is the real problem.
          std::cerr &lt;&lt; "Asked " &lt;&lt; bytesNeeded &lt;&lt; " got " &lt;&lt; len;
      }
      return (int)len;
  }
  
  int main(int argc, char* argv[])
  {
      do try {
          ::openSocket("192.168.6.30", "80");
  
          read(148); // Assume that data[] already has 364 bytes on the first call.
          for (;;)
          {
              read(512); // Full buffers on every subsequent call.
              // Do something with data[] here.
          }
      }
      catch (std::runtime_error) { } while (true);
  }
  </code></pre>
  
  <p>The <code>do try catch while</code> is necessary because the error only happens after I unplug the other side. After the second call to <code>read(148)</code>, the next read(512)` fails.</p>
  
  <p>[update]
  It's not just <code>transfer_exactly</code>. With <code>transfer_at_least(512)</code> I also get the same problem, one superfluous 148 byte read. (The two should behave the same, as reading <em>at least</em> 512 bytes into a buffer that's <em>only</em> 512 bytes cannot read more or less bytes)</p>