socketserver.rst 20.6 KB
Newer Older
1
:mod:`socketserver` --- A framework for network servers
2 3
=======================================================

4
.. module:: socketserver
5 6
   :synopsis: A framework for network servers.

Raymond Hettinger's avatar
Raymond Hettinger committed
7 8 9 10
**Source code:** :source:`Lib/socketserver.py`

--------------

11
The :mod:`socketserver` module simplifies the task of writing network servers.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

There are four basic server classes: :class:`TCPServer` uses the Internet TCP
protocol, which provides for continuous streams of data between the client and
server.  :class:`UDPServer` uses datagrams, which are discrete packets of
information that may arrive out of order or be lost while in transit.  The more
infrequently used :class:`UnixStreamServer` and :class:`UnixDatagramServer`
classes are similar, but use Unix domain sockets; they're not available on
non-Unix platforms.  For more details on network programming, consult a book
such as
W. Richard Steven's UNIX Network Programming or Ralph Davis's Win32 Network
Programming.

These four classes process requests :dfn:`synchronously`; each request must be
completed before the next request can be started.  This isn't suitable if each
request takes a long time to complete, because it requires a lot of computation,
or because it returns a lot of data which the client is slow to process.  The
solution is to create a separate process or thread to handle each request; the
:class:`ForkingMixIn` and :class:`ThreadingMixIn` mix-in classes can be used to
support asynchronous behaviour.

Creating a server requires several steps.  First, you must create a request
handler class by subclassing the :class:`BaseRequestHandler` class and
overriding its :meth:`handle` method; this method will process incoming
requests.  Second, you must instantiate one of the server classes, passing it
the server's address and the request handler class.  Finally, call the
:meth:`handle_request` or :meth:`serve_forever` method of the server object to
process one or many requests.

When inheriting from :class:`ThreadingMixIn` for threaded connection behavior,
you should explicitly declare how you want your threads to behave on an abrupt
Florent Xicluna's avatar
Florent Xicluna committed
42
shutdown.  The :class:`ThreadingMixIn` class defines an attribute
43
*daemon_threads*, which indicates whether or not the server should wait for
Florent Xicluna's avatar
Florent Xicluna committed
44 45 46 47
thread termination.  You should set the flag explicitly if you would like
threads to behave autonomously; the default is :const:`False`, meaning that
Python will not exit until all threads created by :class:`ThreadingMixIn` have
exited.
48 49

Server classes have the same external methods and attributes, no matter what
50
network protocol they use.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84


Server Creation Notes
---------------------

There are five classes in an inheritance diagram, four of which represent
synchronous servers of four types::

   +------------+
   | BaseServer |
   +------------+
         |
         v
   +-----------+        +------------------+
   | TCPServer |------->| UnixStreamServer |
   +-----------+        +------------------+
         |
         v
   +-----------+        +--------------------+
   | UDPServer |------->| UnixDatagramServer |
   +-----------+        +--------------------+

Note that :class:`UnixDatagramServer` derives from :class:`UDPServer`, not from
:class:`UnixStreamServer` --- the only difference between an IP and a Unix
stream server is the address family, which is simply repeated in both Unix
server classes.

Forking and threading versions of each type of server can be created using the
:class:`ForkingMixIn` and :class:`ThreadingMixIn` mix-in classes.  For instance,
a threading UDP server class is created as follows::

   class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass

The mix-in class must come first, since it overrides a method defined in
85
:class:`UDPServer`.  Setting the various attributes also change the
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
behavior of the underlying server mechanism.

To implement a service, you must derive a class from :class:`BaseRequestHandler`
and redefine its :meth:`handle` method.  You can then run various versions of
the service by combining one of the server classes with your request handler
class.  The request handler class must be different for datagram or stream
services.  This can be hidden by using the handler subclasses
:class:`StreamRequestHandler` or :class:`DatagramRequestHandler`.

Of course, you still have to use your head!  For instance, it makes no sense to
use a forking server if the service contains state in memory that can be
modified by different requests, since the modifications in the child process
would never reach the initial state kept in the parent process and passed to
each child.  In this case, you can use a threading server, but you will probably
have to use locks to protect the integrity of the shared data.

On the other hand, if you are building an HTTP server where all data is stored
externally (for instance, in the file system), a synchronous class will
essentially render the service "deaf" while one request is being handled --
which may be for a very long time if a client is slow to receive all the data it
has requested.  Here a threading or forking server is appropriate.

In some cases, it may be appropriate to process part of a request synchronously,
but to finish processing in a forked child depending on the request data.  This
can be implemented by using a synchronous server and doing an explicit fork in
the request handler class :meth:`handle` method.

Another approach to handling multiple simultaneous requests in an environment
114 115 116 117 118 119 120
that supports neither threads nor :func:`~os.fork` (or where these are too
expensive or inappropriate for the service) is to maintain an explicit table of
partially finished requests and to use :func:`~select.select` to decide which
request to work on next (or whether to handle a new incoming request).  This is
particularly important for stream services where each client can potentially be
connected for a long time (if threads or subprocesses cannot be used).  See
:mod:`asyncore` for another way to manage this.
121

122 123
.. XXX should data and methods be intermingled, or separate?
   how should the distinction between class and instance variables be drawn?
124 125 126 127 128


Server Objects
--------------

Benjamin Peterson's avatar
Benjamin Peterson committed
129
.. class:: BaseServer
130

Benjamin Peterson's avatar
Benjamin Peterson committed
131 132 133 134 135 136
   This is the superclass of all Server objects in the module.  It defines the
   interface, given below, but does not implement most of the methods, which is
   done in subclasses.


.. method:: BaseServer.fileno()
137 138 139 140 141 142

   Return an integer file descriptor for the socket on which the server is
   listening.  This function is most commonly passed to :func:`select.select`, to
   allow monitoring multiple servers in the same process.


Benjamin Peterson's avatar
Benjamin Peterson committed
143
.. method:: BaseServer.handle_request()
144

Christian Heimes's avatar
Christian Heimes committed
145 146 147 148 149 150 151
   Process a single request.  This function calls the following methods in
   order: :meth:`get_request`, :meth:`verify_request`, and
   :meth:`process_request`.  If the user-provided :meth:`handle` method of the
   handler class raises an exception, the server's :meth:`handle_error` method
   will be called.  If no request is received within :attr:`self.timeout`
   seconds, :meth:`handle_timeout` will be called and :meth:`handle_request`
   will return.
152 153


Benjamin Peterson's avatar
Benjamin Peterson committed
154
.. method:: BaseServer.serve_forever(poll_interval=0.5)
155

156 157 158 159 160 161
   Handle requests until an explicit :meth:`shutdown` request.  Poll for
   shutdown every *poll_interval* seconds. Ignores :attr:`self.timeout`.  It
   also calls :meth:`service_actions`, which may be used by a subclass or mixin
   to provide actions specific to a given service.  For example, the
   :class:`ForkingMixIn` class uses :meth:`service_actions` to clean up zombie
   child processes.
Christian Heimes's avatar
Christian Heimes committed
162

163
   .. versionchanged:: 3.3
164
       Added ``service_actions`` call to the ``serve_forever`` method.
165 166 167 168


.. method:: BaseServer.service_actions()

169
   This is called in the :meth:`serve_forever` loop. This method can be
170 171
   overridden by subclasses or mixin classes to perform actions specific to
   a given service, such as cleanup actions.
172 173

   .. versionadded:: 3.3
Christian Heimes's avatar
Christian Heimes committed
174

Benjamin Peterson's avatar
Benjamin Peterson committed
175
.. method:: BaseServer.shutdown()
Christian Heimes's avatar
Christian Heimes committed
176

177
   Tell the :meth:`serve_forever` loop to stop and wait until it does.
178 179


Benjamin Peterson's avatar
Benjamin Peterson committed
180
.. attribute:: BaseServer.address_family
181 182

   The family of protocols to which the server's socket belongs.
183
   Common examples are :const:`socket.AF_INET` and :const:`socket.AF_UNIX`.
184 185


Benjamin Peterson's avatar
Benjamin Peterson committed
186
.. attribute:: BaseServer.RequestHandlerClass
187 188 189 190 191

   The user-provided request handler class; an instance of this class is created
   for each request.


Benjamin Peterson's avatar
Benjamin Peterson committed
192
.. attribute:: BaseServer.server_address
193 194 195 196 197 198 199

   The address on which the server is listening.  The format of addresses varies
   depending on the protocol family; see the documentation for the socket module
   for details.  For Internet protocols, this is a tuple containing a string giving
   the address, and an integer port number: ``('127.0.0.1', 80)``, for example.


Benjamin Peterson's avatar
Benjamin Peterson committed
200
.. attribute:: BaseServer.socket
201 202 203

   The socket object on which the server will listen for incoming requests.

Benjamin Peterson's avatar
Benjamin Peterson committed
204

205 206
The server classes support the following class variables:

207
.. XXX should class variables be covered before instance variables, or vice versa?
208

Benjamin Peterson's avatar
Benjamin Peterson committed
209
.. attribute:: BaseServer.allow_reuse_address
210

Florent Xicluna's avatar
Florent Xicluna committed
211
   Whether the server will allow the reuse of an address.  This defaults to
212 213 214
   :const:`False`, and can be set in subclasses to change the policy.


Benjamin Peterson's avatar
Benjamin Peterson committed
215
.. attribute:: BaseServer.request_queue_size
216 217 218 219 220 221 222 223

   The size of the request queue.  If it takes a long time to process a single
   request, any requests that arrive while the server is busy are placed into a
   queue, up to :attr:`request_queue_size` requests.  Once the queue is full,
   further requests from clients will get a "Connection denied" error.  The default
   value is usually 5, but this can be overridden by subclasses.


Benjamin Peterson's avatar
Benjamin Peterson committed
224
.. attribute:: BaseServer.socket_type
225 226

   The type of socket used by the server; :const:`socket.SOCK_STREAM` and
227
   :const:`socket.SOCK_DGRAM` are two common values.
228

Benjamin Peterson's avatar
Benjamin Peterson committed
229 230

.. attribute:: BaseServer.timeout
231

Christian Heimes's avatar
Christian Heimes committed
232 233 234
   Timeout duration, measured in seconds, or :const:`None` if no timeout is
   desired.  If :meth:`handle_request` receives no incoming requests within the
   timeout period, the :meth:`handle_timeout` method is called.
235

Benjamin Peterson's avatar
Benjamin Peterson committed
236

237 238 239 240
There are various server methods that can be overridden by subclasses of base
server classes like :class:`TCPServer`; these methods aren't useful to external
users of the server object.

241
.. XXX should the default implementations of these be documented, or should
242
   it be assumed that the user will look at socketserver.py?
243

Benjamin Peterson's avatar
Benjamin Peterson committed
244
.. method:: BaseServer.finish_request()
245 246 247 248 249

   Actually processes the request by instantiating :attr:`RequestHandlerClass` and
   calling its :meth:`handle` method.


Benjamin Peterson's avatar
Benjamin Peterson committed
250
.. method:: BaseServer.get_request()
251 252 253 254 255 256

   Must accept a request from the socket, and return a 2-tuple containing the *new*
   socket object to be used to communicate with the client, and the client's
   address.


Benjamin Peterson's avatar
Benjamin Peterson committed
257
.. method:: BaseServer.handle_error(request, client_address)
258 259 260 261 262

   This function is called if the :attr:`RequestHandlerClass`'s :meth:`handle`
   method raises an exception.  The default action is to print the traceback to
   standard output and continue handling further requests.

Benjamin Peterson's avatar
Benjamin Peterson committed
263 264

.. method:: BaseServer.handle_timeout()
265

Georg Brandl's avatar
Georg Brandl committed
266 267
   This function is called when the :attr:`timeout` attribute has been set to a
   value other than :const:`None` and the timeout period has passed with no
268 269 270
   requests being received.  The default action for forking servers is
   to collect the status of any child processes that have exited, while
   in threading servers this method does nothing.
271

Benjamin Peterson's avatar
Benjamin Peterson committed
272 273

.. method:: BaseServer.process_request(request, client_address)
274 275 276 277 278 279

   Calls :meth:`finish_request` to create an instance of the
   :attr:`RequestHandlerClass`.  If desired, this function can create a new process
   or thread to handle the request; the :class:`ForkingMixIn` and
   :class:`ThreadingMixIn` classes do this.

Benjamin Peterson's avatar
Benjamin Peterson committed
280

281 282 283
.. Is there any point in documenting the following two functions?
   What would the purpose of overriding them be: initializing server
   instance variables, adding new network families?
284

Benjamin Peterson's avatar
Benjamin Peterson committed
285
.. method:: BaseServer.server_activate()
286 287

   Called by the server's constructor to activate the server.  The default behavior
Florent Xicluna's avatar
Florent Xicluna committed
288
   just :meth:`listen`\ s to the server's socket.  May be overridden.
289 290


Benjamin Peterson's avatar
Benjamin Peterson committed
291
.. method:: BaseServer.server_bind()
292 293 294 295 296

   Called by the server's constructor to bind the socket to the desired address.
   May be overridden.


Benjamin Peterson's avatar
Benjamin Peterson committed
297
.. method:: BaseServer.verify_request(request, client_address)
298

Florent Xicluna's avatar
Florent Xicluna committed
299 300 301 302
   Must return a Boolean value; if the value is :const:`True`, the request will
   be processed, and if it's :const:`False`, the request will be denied.  This
   function can be overridden to implement access controls for a server. The
   default implementation always returns :const:`True`.
303 304 305 306 307 308 309 310 311 312


RequestHandler Objects
----------------------

The request handler class must define a new :meth:`handle` method, and can
override any of the following methods.  A new instance is created for each
request.


Benjamin Peterson's avatar
Benjamin Peterson committed
313
.. method:: RequestHandler.finish()
314

Georg Brandl's avatar
Georg Brandl committed
315
   Called after the :meth:`handle` method to perform any clean-up actions
316 317
   required.  The default implementation does nothing.  If :meth:`setup`
   raises an exception, this function will not be called.
318 319


Benjamin Peterson's avatar
Benjamin Peterson committed
320
.. method:: RequestHandler.handle()
321

Georg Brandl's avatar
Georg Brandl committed
322 323 324 325 326
   This function must do all the work required to service a request.  The
   default implementation does nothing.  Several instance attributes are
   available to it; the request is available as :attr:`self.request`; the client
   address as :attr:`self.client_address`; and the server instance as
   :attr:`self.server`, in case it needs access to per-server information.
327

Georg Brandl's avatar
Georg Brandl committed
328 329 330 331 332 333 334 335 336
   The type of :attr:`self.request` is different for datagram or stream
   services.  For stream services, :attr:`self.request` is a socket object; for
   datagram services, :attr:`self.request` is a pair of string and socket.
   However, this can be hidden by using the request handler subclasses
   :class:`StreamRequestHandler` or :class:`DatagramRequestHandler`, which
   override the :meth:`setup` and :meth:`finish` methods, and provide
   :attr:`self.rfile` and :attr:`self.wfile` attributes.  :attr:`self.rfile` and
   :attr:`self.wfile` can be read or written, respectively, to get the request
   data or return data to the client.
337 338


Benjamin Peterson's avatar
Benjamin Peterson committed
339
.. method:: RequestHandler.setup()
340 341 342 343

   Called before the :meth:`handle` method to perform any initialization actions
   required.  The default implementation does nothing.

Georg Brandl's avatar
Georg Brandl committed
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366

Examples
--------

:class:`socketserver.TCPServer` Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is the server side::

   import socketserver

   class MyTCPHandler(socketserver.BaseRequestHandler):
       """
       The RequestHandler class for our server.

       It is instantiated once per connection to the server, and must
       override the handle() method to implement communication to the
       client.
       """

       def handle(self):
           # self.request is the TCP socket connected to the client
           self.data = self.request.recv(1024).strip()
367
           print("{} wrote:".format(self.client_address[0]))
368
           print(self.data)
Georg Brandl's avatar
Georg Brandl committed
369
           # just send back the same data, but upper-cased
370
           self.request.sendall(self.data.upper())
Georg Brandl's avatar
Georg Brandl committed
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390

   if __name__ == "__main__":
       HOST, PORT = "localhost", 9999

       # Create the server, binding to localhost on port 9999
       server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)

       # Activate the server; this will keep running until you
       # interrupt the program with Ctrl-C
       server.serve_forever()

An alternative request handler class that makes use of streams (file-like
objects that simplify communication by providing the standard file interface)::

   class MyTCPHandler(socketserver.StreamRequestHandler):

       def handle(self):
           # self.rfile is a file-like object created by the handler;
           # we can now use e.g. readline() instead of raw recv() calls
           self.data = self.rfile.readline().strip()
391
           print("{} wrote:".format(self.client_address[0]))
392
           print(self.data)
Georg Brandl's avatar
Georg Brandl committed
393 394 395 396 397 398 399
           # Likewise, self.wfile is a file-like object used to write back
           # to the client
           self.wfile.write(self.data.upper())

The difference is that the ``readline()`` call in the second handler will call
``recv()`` multiple times until it encounters a newline character, while the
single ``recv()`` call in the first handler will just return what has been sent
400
from the client in one ``sendall()`` call.
Georg Brandl's avatar
Georg Brandl committed
401 402 403 404 405 406 407 408 409 410 411 412 413


This is the client side::

   import socket
   import sys

   HOST, PORT = "localhost", 9999
   data = " ".join(sys.argv[1:])

   # Create a socket (SOCK_STREAM means a TCP socket)
   sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

414 415 416
   try:
       # Connect to server and send data
       sock.connect((HOST, PORT))
417
       sock.sendall(bytes(data + "\n", "utf-8"))
Georg Brandl's avatar
Georg Brandl committed
418

419 420 421 422
       # Receive data from the server and shut down
       received = str(sock.recv(1024), "utf-8")
   finally:
       sock.close()
Georg Brandl's avatar
Georg Brandl committed
423

424 425
   print("Sent:     {}".format(data))
   print("Received: {}".format(received))
Georg Brandl's avatar
Georg Brandl committed
426 427 428 429 430 431 432 433


The output of the example should look something like this:

Server::

   $ python TCPServer.py
   127.0.0.1 wrote:
434
   b'hello world with TCP'
Georg Brandl's avatar
Georg Brandl committed
435
   127.0.0.1 wrote:
436
   b'python is nice'
Georg Brandl's avatar
Georg Brandl committed
437 438 439 440 441

Client::

   $ python TCPClient.py hello world with TCP
   Sent:     hello world with TCP
442
   Received: HELLO WORLD WITH TCP
Georg Brandl's avatar
Georg Brandl committed
443 444
   $ python TCPClient.py python is nice
   Sent:     python is nice
445
   Received: PYTHON IS NICE
Georg Brandl's avatar
Georg Brandl committed
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465


:class:`socketserver.UDPServer` Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is the server side::

   import socketserver

   class MyUDPHandler(socketserver.BaseRequestHandler):
       """
       This class works similar to the TCP handler class, except that
       self.request consists of a pair of data and client socket, and since
       there is no connection the client address must be given explicitly
       when sending data back via sendto().
       """

       def handle(self):
           data = self.request[0].strip()
           socket = self.request[1]
466
           print("{} wrote:".format(self.client_address[0]))
467
           print(data)
Georg Brandl's avatar
Georg Brandl committed
468 469 470
           socket.sendto(data.upper(), self.client_address)

   if __name__ == "__main__":
471 472 473
       HOST, PORT = "localhost", 9999
       server = socketserver.UDPServer((HOST, PORT), MyUDPHandler)
       server.serve_forever()
Georg Brandl's avatar
Georg Brandl committed
474 475 476 477 478 479

This is the client side::

   import socket
   import sys

480
   HOST, PORT = "localhost", 9999
Georg Brandl's avatar
Georg Brandl committed
481 482 483 484 485 486 487
   data = " ".join(sys.argv[1:])

   # SOCK_DGRAM is the socket type to use for UDP sockets
   sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

   # As you can see, there is no connect() call; UDP has no connections.
   # Instead, data is directly sent to the recipient via sendto().
488 489
   sock.sendto(bytes(data + "\n", "utf-8"), (HOST, PORT))
   received = str(sock.recv(1024), "utf-8")
Georg Brandl's avatar
Georg Brandl committed
490

491 492
   print("Sent:     {}".format(data))
   print("Received: {}".format(received))
Georg Brandl's avatar
Georg Brandl committed
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511

The output of the example should look exactly like for the TCP server example.


Asynchronous Mixins
~~~~~~~~~~~~~~~~~~~

To build asynchronous handlers, use the :class:`ThreadingMixIn` and
:class:`ForkingMixIn` classes.

An example for the :class:`ThreadingMixIn` class::

   import socket
   import threading
   import socketserver

   class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):

       def handle(self):
512
           data = str(self.request.recv(1024), 'ascii')
513
           cur_thread = threading.current_thread()
514
           response = bytes("{}: {}".format(cur_thread.name, data), 'ascii')
515
           self.request.sendall(response)
Georg Brandl's avatar
Georg Brandl committed
516 517 518 519 520 521 522

   class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
       pass

   def client(ip, port, message):
       sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
       sock.connect((ip, port))
523
       try:
524
           sock.sendall(bytes(message, 'ascii'))
525 526 527 528
           response = str(sock.recv(1024), 'ascii')
           print("Received: {}".format(response))
       finally:
           sock.close()
Georg Brandl's avatar
Georg Brandl committed
529 530 531 532 533 534 535 536 537 538 539 540

   if __name__ == "__main__":
       # Port 0 means to select an arbitrary unused port
       HOST, PORT = "localhost", 0

       server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
       ip, port = server.server_address

       # Start a thread with the server -- that thread will then start one
       # more thread for each request
       server_thread = threading.Thread(target=server.serve_forever)
       # Exit the server thread when the main thread terminates
541
       server_thread.daemon = True
Georg Brandl's avatar
Georg Brandl committed
542
       server_thread.start()
Benjamin Peterson's avatar
Benjamin Peterson committed
543
       print("Server loop running in thread:", server_thread.name)
Georg Brandl's avatar
Georg Brandl committed
544

545 546 547
       client(ip, port, "Hello World 1")
       client(ip, port, "Hello World 2")
       client(ip, port, "Hello World 3")
Georg Brandl's avatar
Georg Brandl committed
548 549 550

       server.shutdown()

551

Georg Brandl's avatar
Georg Brandl committed
552 553 554 555
The output of the example should look something like this::

   $ python ThreadedTCPServer.py
   Server loop running in thread: Thread-1
556 557 558
   Received: Thread-2: Hello World 1
   Received: Thread-3: Hello World 2
   Received: Thread-4: Hello World 3
Georg Brandl's avatar
Georg Brandl committed
559 560 561 562


The :class:`ForkingMixIn` class is used in the same way, except that the server
will spawn a new process for each request.