title: boost asio tcp async read/write
body: <p>i have an understanding problem how boost asio handles this:</p>
  
  <p><img src="https://i.stack.imgur.com/vp2Rn.png" alt="enter image description here"></p>
  
  <p>When I watch my request response on client side, I can use following boost example <a href="http://www.boost.org/doc/libs/1_58_0/doc/html/boost_asio/example/cpp11/chat/chat_client.cpp" rel="nofollow noreferrer">Example</a></p>
  
  <p>But I don't understand what happens if the server send every X ms some status information to the client. Have I open a serperate socket for this or can my client difference which is the request, response and the cycleMessage ?</p>
  
  <p>Can it happen, that the client send a Request and read is as cycleMessage? Because he is also waiting for async_read because of this Message?</p>
  
  <hr>
  
  <pre><code>class TcpConnectionServer : public boost::enable_shared_from_this&lt;TcpConnectionServer&gt;
  {
  public:
      typedef  boost::shared_ptr&lt;TcpConnectionServer&gt; pointer;
      static pointer create(boost::asio::io_service&amp; io_service)
      {
          return pointer(new TcpConnectionServer(io_service));
      }
      boost::asio::ip::tcp::socket&amp; socket()
      {
          return m_socket;
      }
      void Start()
      {
          SendCycleMessage();
          boost::asio::async_read(
                  m_socket, boost::asio::buffer(m_data, m_dataSize),
                  boost::bind(&amp;TcpConnectionServer::handle_read_data, shared_from_this(), boost::asio::placeholders::error));
      }
  
  private:
      TcpConnectionServer(boost::asio::io_service&amp; io_service)
          : m_socket(io_service),m_cycleUpdateRate(io_service,boost::posix_time::seconds(1))
        {
  
        }
      void handle_read_data(const boost::system::error_code&amp; error_code)
      {
          if (!error_code)
          {
          std::string answer=doSomeThingWithData(m_data);
          writeImpl(answer);
  
          boost::asio::async_read(
                  m_socket, boost::asio::buffer(m_data, m_dataSize),
                  boost::bind(&amp;TcpConnectionServer::handle_read_data, shared_from_this(), boost::asio::placeholders::error));
          }
          else
          {
  
              std::cout &lt;&lt; error_code.message() &lt;&lt; "ERROR DELETE READ \n";
              // delete this;
          }
      }
  
  
      void SendCycleMessage()
      {
          std::string data = "some usefull data";
          writeImpl(data);
          m_cycleUpdateRate.expires_from_now(boost::posix_time::seconds(1));
          m_cycleUpdateRate.async_wait(boost::bind(&amp;TcpConnectionServer::SendTracedParameter,this));
      }
  
      void writeImpl(const std::string&amp; message)
      {
          m_messageOutputQueue.push_back(message);
          if (m_messageOutputQueue.size() &gt; 1)
          {
              // outstanding async_write
              return;
          }
  
          this-&gt;write();
      }
  
      void write()
      {
          m_message = m_messageOutputQueue[0];
          boost::asio::async_write(
                  m_socket,
                  boost::asio::buffer(m_message),
                  boost::bind(&amp;TcpConnectionServer::writeHandler, this, boost::asio::placeholders::error,
                              boost::asio::placeholders::bytes_transferred));
      }
  
      void writeHandler(const boost::system::error_code&amp; error, const size_t bytesTransferred)
      {
          m_messageOutputQueue.pop_front();
          if (error)
          {
              std::cerr &lt;&lt; "could not write: " &lt;&lt; boost::system::system_error(error).what() &lt;&lt; std::endl;
              return;
          }
  
          if (!m_messageOutputQueue.empty())
          {
              // more messages to send
              this-&gt;write();
          }
      }
  
      boost::asio::ip::tcp::socket m_socket;
      boost::asio::deadline_timer m_cycleUpdateRate;
      std::string m_message;
  
      const size_t m_sizeOfHeader = 5;
      boost::array&lt;char, 5&gt; m_headerData;
      std::vector&lt;char&gt; m_bodyData;
  
      std::deque&lt;std::string&gt; m_messageOutputQueue;
  };
  </code></pre>
  
  <p>With this implementation I will not need boost::asio::strand or? Because I will not modify the m_messageOutputQueue from an other thread.</p>
  
  <p>But when I have on my client side an m_messageOutputQueue which i can access from an other thread on this point I will need strand? Because then i need the synchronization? Did I understand something wrong?</p>