cpython: 8b71cd67f548 (original) (raw)

--- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -10,16 +10,34 @@ The :mod:socketserver module simplifies the task of writing network servers. -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. +There are four basic concrete server classes: + + +.. class:: TCPServer(server_address, RequestHandlerClass, bind_and_activate=True) +

+ +.. class:: UDPServer(server_address, RequestHandlerClass, bind_and_activate=True) +

+ +.. class:: UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)

+

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 @@ -31,10 +49,12 @@ 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 +overriding its :meth:~BaseRequestHandler.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. Then call the -:meth:handle_request or :meth:serve_forever method of the server object to +:meth:~BaseServer.handle_request or +:meth:~BaseServer.serve_forever method of the server object to process one or many requests. Finally, call :meth:~BaseServer.server_close to close the socket. @@ -76,18 +96,33 @@ Note that :class:UnixDatagramServer de 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:: ForkingMixIn

+

-The mix-in class must come first, since it overrides a method defined in -:class:UDPServer. Setting the various attributes also change the -behavior of the underlying server mechanism. +.. class:: ForkingTCPServer

+

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 +and redefine its :meth:~BaseRequestHandler.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 @@ -109,7 +144,7 @@ has requested. Here a threading or fork 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. +the request handler class :meth:~BaseRequestHandler.handle method. Another approach to handling multiple simultaneous requests in an environment that supports neither threads nor :func:~os.fork (or where these are too @@ -127,227 +162,240 @@ connected for a long time (if threads or Server Objects -------------- -.. class:: BaseServer +.. class:: BaseServer(server_address, RequestHandlerClass) 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

-.. method:: BaseServer.fileno()

-.. method:: BaseServer.handle_request()

-.. method:: BaseServer.serve_forever(poll_interval=0.5)

-.. method:: BaseServer.service_actions()

+

-.. method:: BaseServer.shutdown()

-.. method:: BaseServer.server_close()

-.. attribute:: BaseServer.address_family

-.. attribute:: BaseServer.RequestHandlerClass

-.. attribute:: BaseServer.server_address

-.. attribute:: BaseServer.socket

-The server classes support the following class variables: - -.. XXX should class variables be covered before instance variables, or vice versa?

-.. attribute:: BaseServer.allow_reuse_address -

-.. attribute:: BaseServer.request_queue_size

-.. attribute:: BaseServer.socket_type

-.. attribute:: BaseServer.timeout

+

-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.

-.. XXX should the default implementations of these be documented, or should

-.. method:: BaseServer.finish_request() -

-.. method:: BaseServer.get_request()

-.. method:: BaseServer.handle_error(request, client_address)

-.. method:: BaseServer.handle_timeout()

-.. method:: BaseServer.process_request(request, client_address)

-.. Is there any point in documenting the following two functions?

-.. method:: BaseServer.server_activate() -

-.. method:: BaseServer.server_bind()

-.. method:: BaseServer.verify_request(request, client_address) +Request Handler Objects +----------------------- + +.. class:: BaseRequestHandler

-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.

- -.. method:: RequestHandler.finish() -

-.. method:: RequestHandler.handle() -

+

-.. method:: RequestHandler.setup()

+

+

Examples @@ -362,7 +410,7 @@ This is the server side:: class MyTCPHandler(socketserver.BaseRequestHandler): """

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