title: Python Bidirectional TCP Socket Hanging on socket.recv
body: <p>Referencing this example (and the <a href="https://docs.python.org/2/library/socket.html" rel="nofollow noreferrer">docs</a>): <a href="https://pymotw.com/2/socket/tcp.html" rel="nofollow noreferrer">https://pymotw.com/2/socket/tcp.html</a> I am trying to achieve bidirectional communication with blocking sockets between a client and a server using TCP.</p>
  
  <p>I can get one-way communication to work from <code>client-&gt;server</code> or <code>server-&gt;client</code>, but the socket remains blocked or "hangs" when trying to receive messages on both the server and client. I am using a simple algorithm(<code>recvall</code>), which uses <code>recv</code>, to consolidate the packets into the full message.</p>
  
  <p>I understand the sockets remain blocked by design until all the data is sent or read(right?), but isn't that what <code>sendall</code> and <code>recvall</code> take care of? How come disabling <code>recv</code> on either the client or server "unblocks" it and causes it to work? And ultimately what am I doing wrong that is causing the socket to stay blocked?</p>
  
  <p>Here is my code, the only fundamental difference really being the messages that are sent:</p>
  
  <p><code>recvall(socket)</code>(shared between client and server):</p>
  
  <pre><code>def recvall(socket):
      data = ''
      while True:
          packet = socket.recv(16)
          if not packet: break
          data += packet
  
      return data
  </code></pre>
  
  <p><code>server.py</code> (run first):</p>
  
  <pre><code>import socket
  
  host = 'localhost'
  port = 8080
  
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.bind((host, port))
  s.listen(5)
  
  while True:
      (client, address) = s.accept()
      print 'client connected'
  
      try:
          print recvall(client)
          client.sendall('hello client')
      finally:
          client.close()
  </code></pre>
  
  <p><code>client.py</code>:
      import socket</p>
  
  <pre><code>s = socket.create_connection((args.ip, args.port))
  
  try:
      s.sendall('hello server')
      print recvall(s)
  finally:
      s.close()
  </code></pre>