title: How to process multiple commands to read from socket at the same time in Tornado asynchronous TCP?
body: <p>My TCP server is made with Tornado's asynchronous TCP. The client is written in C.</p>
  
  <p>Server code:</p>
  
  <pre><code>#! /usr/bin/env python
  #coding=utf-8
  
  from tornado.tcpserver import TCPServer
  from tornado.ioloop import IOLoop
  
  class TcpConnection(object):
      def __init__(self,stream,address):
          self._stream=stream
          self._address=address
          self._stream.set_close_callback(self.on_close)
          self.send_message(b'hello \n')
          self.send_message(b'world \n')
  
      def read_message(self):
          self._stream.read_until(b'\n', self.handle_message)
  
      def handle_message(self,data):
          print(data)
  
      def send_message(self,data):
          self._stream.write(data)
          self.read_message()
  
      def on_close(self):
          print("the monitored %d has left",self._address)
  
  class MonitorServer(TCPServer):
      def handle_stream(self,stream,address):
          print("new connection",address,stream)
          TcpConnection(stream,address)
  
  if  __name__=='__main__':
      print('server start .....')
      server=MonitorServer()
      server.listen(20000)
      IOLoop.instance().start()
  </code></pre>
  
  <p>Client code:</p>
  
  <pre><code>#include &lt;Winsock2.h&gt;
  #include &lt;stdio.h&gt;
  #pragma comment(lib, "ws2_32.lib")
  
  typedef struct SytemInit
  {
      char computer[32];      
      char user[32];              
      char os[256];               
      char processor[256];    
      char mem[128];          
      char disk[128];             
  }SYSTEMINIT;
  
  typedef struct Command
  {
      int  commandType;                             
      char commandInfo[256];                 
  }COMMAND;
  
  void main()
  {
      int err;
      SYSTEMINIT message;
      COMMAND recvBuf;
  
      SOCKET sockClient; 
      SOCKADDR_IN addrServer; 
  
      WSADATA wsaData;
      WORD wVersionRequested;
  
      wVersionRequested = MAKEWORD( 2, 2 );
  
      err = WSAStartup( wVersionRequested, &amp;wsaData );
  
      if ( err != 0 )
      {
          return;
      }
  
      if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
      {
          WSACleanup( );
          return;
      }
  
      sockClient = socket(AF_INET, SOCK_STREAM, 0);
  
      addrServer.sin_addr.S_un.S_addr = inet_addr("172.16.110.1");  
      addrServer.sin_family = AF_INET;                           
      addrServer.sin_port = htons(20000);                         
  
      connect(sockClient, (SOCKADDR *)&amp;addrServer, sizeof(SOCKADDR));
  
      recv(sockClient, (char*)&amp;recvBuf, 100, 0);
  
      strcpy(message.computer,"zz-pc");
      strcpy(message.disk,"zz-disk");
      strcpy(message.mem,"zz-men");
      strcpy(message.os,"zz-os");
      strcpy(message.processor,"zz-processor");
      strcpy(message.user,"zz-user");
  
      send(sockClient, (char*)&amp;message, sizeof(message) + 1, 0);
  
      closesocket(sockClient);
      WSACleanup();
  }
  </code></pre>
  
  <p>I get the following error when I execute them:</p>
  
  <pre><code>ERROR:tornado.application:Error in connection callback
  Traceback (most recent call last):
    File "/usr/local/lib/python3.4/dist-packages/tornado/tcpserver.py", line 269, in _handle_connection
      future = self.handle_stream(stream, address)
    File "/home/zz/PycharmProjects/monitor/test.py", line 34, in handle_stream
      TcpConnection(stream,address)
    File "/home/zz/PycharmProjects/monitor/test.py", line 15, in __init__
      self.send_message(b'world \n')
    File "/home/zz/PycharmProjects/monitor/test.py", line 25, in send_message
      self.read_message()
    File "/home/zz/PycharmProjects/monitor/test.py", line 18, in read_message
      self._stream.read_until(b'\n', self.handle_message)
    File "/usr/local/lib/python3.4/dist-packages/tornado/iostream.py", line 270, in read_until
      future = self._set_read_callback(callback)
    File "/usr/local/lib/python3.4/dist-packages/tornado/iostream.py", line 658, in _set_read_callback
      assert self._read_callback is None, "Already reading"
  AssertionError: Already reading
  </code></pre>
  
  <p>I guess this error is because <code>self.send_message(b'hello \n')</code> and <code>self.send_message(b'world \n')</code> read from the socket at the same time.
  How can I solve this?</p>