class_docstr: A non-blocking, single-threaded TCP server.
  
  To use `TCPServer`, define a subclass which overrides the `handle_stream`
  method. For example, a simple echo server could be defined like this::
  
    from tornado.tcpserver import TCPServer
    from tornado.iostream import StreamClosedError
    from tornado import gen
  
    class EchoServer(TCPServer):
        @gen.coroutine
        def handle_stream(self, stream, address):
            while True:
                try:
                    data = yield stream.read_until(b"\n")
                    yield stream.write(data)
                except StreamClosedError:
                    break
  
  To make this server serve SSL traffic, send the ``ssl_options`` keyword
  argument with an `ssl.SSLContext` object. For compatibility with older
  versions of Python ``ssl_options`` may also be a dictionary of keyword
  arguments for the `ssl.wrap_socket` method.::
  
     ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
     ssl_ctx.load_cert_chain(os.path.join(data_dir, "mydomain.crt"),
                             os.path.join(data_dir, "mydomain.key"))
     TCPServer(ssl_options=ssl_ctx)
  
  `TCPServer` initialization follows one of three patterns:
  
  1. `listen`: simple single-process::
  
          server = TCPServer()
          server.listen(8888)
          IOLoop.current().start()
  
  2. `bind`/`start`: simple multi-process::
  
          server = TCPServer()
          server.bind(8888)
          server.start(0)  # Forks multiple sub-processes
          IOLoop.current().start()
  
     When using this interface, an `.IOLoop` must *not* be passed
     to the `TCPServer` constructor.  `start` will always start
     the server on the default singleton `.IOLoop`.
  
  3. `add_sockets`: advanced multi-process::
  
          sockets = bind_sockets(8888)
          tornado.process.fork_processes(0)
          server = TCPServer()
          server.add_sockets(sockets)
          IOLoop.current().start()
  
     The `add_sockets` interface is more complicated, but it can be
     used with `tornado.process.fork_processes` to give you more
     flexibility in when the fork happens.  `add_sockets` can
     also be used in single-process servers if you want to create
     your listening sockets in some way other than
     `~tornado.netutil.bind_sockets`.
  
  .. versionadded:: 3.1
     The ``max_buffer_size`` argument.
code: def _handle_connection(self, connection, address):
      if self.ssl_options is not None:
          assert ssl, "Python 2.6+ and OpenSSL required for SSL"
          try:
              connection = ssl_wrap_socket(
                  connection,
                  self.ssl_options,
                  server_side=True,
                  do_handshake_on_connect=False,
              )
          except ssl.SSLError as err:
              if err.args[0] == ssl.SSL_ERROR_EOF:
                  return connection.close()
              else:
                  raise
          except socket.error as err:
              # If the connection is closed immediately after it is created
              # (as in a port scan), we can get one of several errors.
              # wrap_socket makes an internal call to getpeername,
              # which may return either EINVAL (Mac OS X) or ENOTCONN
              # (Linux).  If it returns ENOTCONN, this error is
              # silently swallowed by the ssl module, so we need to
              # catch another error later on (AttributeError in
              # SSLIOStream._do_ssl_handshake).
              # To test this behavior, try nmap with the -sT flag.
              # https://github.com/tornadoweb/tornado/pull/750
              if errno_from_exception(err) in (
                  errno.ECONNABORTED,
                  errno.EINVAL,
              ):
                  return connection.close()
              else:
                  raise
      try:
          if self.ssl_options is not None:
              stream = SSLIOStream(
                  connection,
                  io_loop=self.io_loop,
                  max_buffer_size=self.max_buffer_size,
                  read_chunk_size=self.read_chunk_size,
              )
          else:
              stream = IOStream(
                  connection,
                  io_loop=self.io_loop,
                  max_buffer_size=self.max_buffer_size,
                  read_chunk_size=self.read_chunk_size,
              )
  
          future = self.handle_stream(stream, address)
          if future is not None:
              self.io_loop.add_future(
                  gen.convert_yielded(future), lambda f: f.result()
              )
      except Exception:
          app_log.error("Error in connection callback", exc_info=True)
  
imports: from __future__ import absolute_import, division, print_function
  import errno
  import os
  import socket
  from tornado import gen
  from tornado.log import app_log
  from tornado.ioloop import IOLoop
  from tornado.iostream import IOStream, SSLIOStream
  from tornado.netutil import bind_sockets, add_accept_handler, ssl_wrap_socket
  from tornado import process
  from tornado.util import errno_from_exception
label_desc: Use image node_id 9 for calling the TCPServer obj's underlying member method code with example usage: obj._handle_connection(connection, address) and returns: connection, connection