title: Python: SocketServer closes TCP connection unexpectedly
body: <p>I would like to implement a TCP/IP network client application that sends requests to a Python <a href="https://docs.python.org/2/library/socketserver.html" rel="nofollow noreferrer">SocketServer</a> and expects responses in return. I have started out with the official Python <a href="https://docs.python.org/2/library/socketserver.html#socketserver-tcpserver-example" rel="nofollow noreferrer">SocketServer sample code</a>:</p>
  
  <p><code>server.py:</code></p>
  
  <pre><code>#!/usr/bin/env python
  # encoding: utf-8
  
  import SocketServer
  
  class MyTCPHandler(SocketServer.StreamRequestHandler):
  
      def handle(self):
          request  = self.rfile.readline().strip()
          print "RX [%s]: %s" % (self.client_address[0], request)
  
          response = self.processRequest(request)
  
          print "TX [%s]: %s" % (self.client_address[0], response)
          self.wfile.write(response)
  
      def processRequest(self, message):
          if   message == 'request type 01':
              return 'response type 01'
          elif message == 'request type 02':
              return 'response type 02'
  
  if __name__ == "__main__":
      server = SocketServer.TCPServer(('localhost', 12345), MyTCPHandler)
      server.serve_forever()
  </code></pre>
  
  <p><code>client.py:</code></p>
  
  <pre><code>#!/usr/bin/env python
  # encoding: utf-8
  
  import socket
  
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  
  try:
      sock.connect(('127.0.0.1', 12345))
  
      data = 'request type 01'
      sent = sock.sendall(data + '\n')
      if sent == 0:
          raise RuntimeError("socket connection broken")
  
      received = sock.recv(1024)
      print "Sent:     {}".format(data)
      print "Received: {}".format(received)
  
      data = 'request type 02'
      sent = sock.sendall(data + '\n')
      if sent == 0:
          raise RuntimeError("socket connection broken")
  
      received = sock.recv(1024)
      print "Sent:     {}".format(data)
      print "Received: {}".format(received)
  
  except Exception as e:
      print e
  
  finally:
      sock.close()
  </code></pre>
  
  <p><code>server.py</code> output:</p>
  
  <pre><code>RX [127.0.0.1]: request type 01
  TX [127.0.0.1]: response type 01
  </code></pre>
  
  <p><code>client.py</code> output:</p>
  
  <pre><code>Sent:     request type 01
  Received: response type 01
  [Errno 54] Connection reset by peer
  </code></pre>
  
  <p>What am doing wrong ? It seems the server is closing the connection. How can I make it stay open ?</p>
  
  <p>Note: This is a follow-up question to <a href="https://stackoverflow.com/q/29549878">C++/Qt: QTcpSocket won&#39;t write after reading</a></p>
  
  <p><strong>Update (after <a href="https://stackoverflow.com/a/29572128">abarnert's answer</a>):</strong></p>
  
  <p>What I take away from this is that <code>SocketServer.StreamRequestHandler</code> is not the most recent design and while it allows me to connect over a network, it doesn't really support me with all the TCP/IP-related aspects I need to take care of to implement robust communication.</p>
  
  <p>This has been addressed in Python 3 with <a href="https://docs.python.org/3.4/library/asyncio.html" rel="nofollow noreferrer">asyncio</a>, but as the project lives in Python 2, that's not an option. I have therefore implemented the server and client described above in <a href="https://twistedmatrix.com/" rel="nofollow noreferrer">Twisted</a>:</p>
  
  <p><code>server.py:</code></p>
  
  <pre><code>#!/usr/bin/env python
  # encoding: utf-8
  
  from twisted.internet.protocol import Factory
  from twisted.protocols.basic import LineReceiver
  from twisted.internet import reactor
  
  class SimpleProtocol(LineReceiver):
  
      def connectionMade(self):
          print 'connectionMade'
  
      # NOTE: lineReceived(...) doesn't seem to get called
  
      def dataReceived(self, data):
          print 'dataReceived'
          print 'RX: %s' % data
  
          if   data == 'request type 01':
              response = 'response type 01'
          elif data == 'request type 02':
              response = 'response type 02'
          else:
              response = 'unsupported request'
  
          print 'TX: %s' % response
          self.sendLine(response)
  
  class SimpleProtocolFactory(Factory):
  
      def buildProtocol(self, addr):
          return SimpleProtocol()
  
  reactor.listenTCP(12345, SimpleProtocolFactory(), interface='127.0.0.1')
  reactor.run()
  </code></pre>
  
  <p><code>client.py:</code></p>
  
  <pre><code>#!/usr/bin/env python
  # encoding: utf-8
  
  from twisted.internet import reactor
  from twisted.internet.protocol import Protocol
  from twisted.internet.endpoints import TCP4ClientEndpoint, connectProtocol
  
  class SimpleClientProtocol(Protocol):
      def sendMessage(self, msg):
          print "[TX]: %s" % msg
          self.transport.write(msg)
  
  def gotProtocol(p):
      p.sendMessage('request type 01')
      reactor.callLater(1, p.sendMessage, 'request type 02')
      reactor.callLater(2, p.transport.loseConnection)
  
  point = TCP4ClientEndpoint(reactor, '127.0.0.1', 12345)
  d = connectProtocol(point, SimpleClientProtocol())
  d.addCallback(gotProtocol)
  reactor.run()
  </code></pre>
  
  <p>The client doesn't close, but idles until <kbd>CTRL</kbd>+<kbd>C</kbd>. Twisted might take a while to get my head around, but for the job at hand, it clearly seems more reasonable to employ a tested and tried framework than to do all this groundwork myself.</p>
  
  <p><strong>NOTE:</strong> This is continued at <a href="https://stackoverflow.com/q/29683769">Twisted XmlStream: How to connect to events?</a></p>