tornado.tcpserver
— Basic IOStream
-based TCP server¶
A non-blocking, single-threaded TCP server.
- class tornado.tcpserver.TCPServer(ssl_options: Dict[str, Any] | SSLContext | None = None, max_buffer_size: int | None = None, read_chunk_size: int | None = None)[source]¶
A non-blocking, single-threaded TCP server.
To use
TCPServer
, define a subclass which overrides thehandle_stream
method. For example, a simple echo server could be defined like this:from tornado.tcpserver import TCPServer from tornado.iostream import StreamClosedError class EchoServer(TCPServer): async def handle_stream(self, stream, address): while True: try: data = await stream.read_until(b"\n") await stream.write(data) except StreamClosedError: break
To make this server serve SSL traffic, send the
ssl_options
keyword argument with anssl.SSLContext
object. For compatibility with older versions of Pythonssl_options
may also be a dictionary of keyword arguments for thessl.SSLContext.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:listen
: single-process:async def main(): server = TCPServer() server.listen(8888) await asyncio.Event().wait() asyncio.run(main())
While this example does not create multiple processes on its own, when the
reuse_port=True
argument is passed tolisten()
you can run the program multiple times to create a multi-process service.add_sockets
: multi-process:sockets = bind_sockets(8888) tornado.process.fork_processes(0) async def post_fork_main(): server = TCPServer() server.add_sockets(sockets) await asyncio.Event().wait() asyncio.run(post_fork_main())
The
add_sockets
interface is more complicated, but it can be used withtornado.process.fork_processes
to run a multi-process service with all worker processes forked from a single parent.add_sockets
can also be used in single-process servers if you want to create your listening sockets in some way other thanbind_sockets
.Note that when using this pattern, nothing that touches the event loop can be run before
fork_processes
.bind
/start
: simple deprecated multi-process:server = TCPServer() server.bind(8888) server.start(0) # Forks multiple sub-processes IOLoop.current().start()
This pattern is deprecated because it requires interfaces in the
asyncio
module that have been deprecated since Python 3.10. Support for creating multiple processes in thestart
method will be removed in a future version of Tornado.
Added in version 3.1: The
max_buffer_size
argument.Changed in version 5.0: The
io_loop
argument has been removed.- listen(port: int, address: str | None = None, family: AddressFamily = AddressFamily.AF_UNSPEC, backlog: int = 128, flags: int | None = None, reuse_port: bool = False) None [source]¶
Starts accepting connections on the given port.
This method may be called more than once to listen on multiple ports.
listen
takes effect immediately; it is not necessary to callTCPServer.start
afterwards. It is, however, necessary to start the event loop if it is not already running.All arguments have the same meaning as in
tornado.netutil.bind_sockets
.Changed in version 6.2: Added
family
,backlog
,flags
, andreuse_port
arguments to matchtornado.netutil.bind_sockets
.
- add_sockets(sockets: Iterable[socket]) None [source]¶
Makes this server start accepting connections on the given sockets.
The
sockets
parameter is a list of socket objects such as those returned bybind_sockets
.add_sockets
is typically used in combination with that method andtornado.process.fork_processes
to provide greater control over the initialization of a multi-process server.
- add_socket(socket: socket) None [source]¶
Singular version of
add_sockets
. Takes a single socket object.
- bind(port: int, address: str | None = None, family: AddressFamily = AddressFamily.AF_UNSPEC, backlog: int = 128, flags: int | None = None, reuse_port: bool = False) None [source]¶
Binds this server to the given port on the given address.
To start the server, call
start
. If you want to run this server in a single process, you can calllisten
as a shortcut to the sequence ofbind
andstart
calls.Address may be either an IP address or hostname. If it’s a hostname, the server will listen on all IP addresses associated with the name. Address may be an empty string or None to listen on all available interfaces. Family may be set to either
socket.AF_INET
orsocket.AF_INET6
to restrict to IPv4 or IPv6 addresses, otherwise both will be used if available.The
backlog
argument has the same meaning as forsocket.listen
. Thereuse_port
argument has the same meaning as forbind_sockets
.This method may be called multiple times prior to
start
to listen on multiple ports or interfaces.Changed in version 4.4: Added the
reuse_port
argument.Changed in version 6.2: Added the
flags
argument to matchbind_sockets
.Deprecated since version 6.2: Use either
listen()
oradd_sockets()
instead ofbind()
andstart()
.
- start(num_processes: int | None = 1, max_restarts: int | None = None) None [source]¶
Starts this server in the
IOLoop
.By default, we run the server in this process and do not fork any additional child process.
If num_processes is
None
or <= 0, we detect the number of cores available on this machine and fork that number of child processes. If num_processes is given and > 1, we fork that specific number of sub-processes.Since we use processes and not threads, there is no shared memory between any server code.
Note that multiple processes are not compatible with the autoreload module (or the
autoreload=True
option totornado.web.Application
which defaults to True whendebug=True
). When using multiple processes, no IOLoops can be created or referenced until after the call toTCPServer.start(n)
.Values of
num_processes
other than 1 are not supported on Windows.The
max_restarts
argument is passed tofork_processes
.Changed in version 6.0: Added
max_restarts
argument.Deprecated since version 6.2: Use either
listen()
oradd_sockets()
instead ofbind()
andstart()
.
- stop() None [source]¶
Stops listening for new connections.
Requests currently in progress may still continue after the server is stopped.
- handle_stream(stream: IOStream, address: tuple) Awaitable[None] | None [source]¶
Override to handle a new
IOStream
from an incoming connection.This method may be a coroutine; if so any exceptions it raises asynchronously will be logged. Accepting of incoming connections will not be blocked by this coroutine.
If this
TCPServer
is configured for SSL,handle_stream
may be called before the SSL handshake has completed. UseSSLIOStream.wait_for_handshake
if you need to verify the client’s certificate or use NPN/ALPN.Changed in version 4.2: Added the option for this method to be a coroutine.