@@ -52,11 +52,12 @@ handler class by subclassing the :class:`BaseRequestHandler` class and
5252overriding its :meth: `~BaseRequestHandler.handle ` method;
5353this method will process incoming
5454requests. Second, you must instantiate one of the server classes, passing it
55- the server's address and the request handler class. Then call the
55+ the server's address and the request handler class. It is recommended to use
56+ the server in a :keyword: `with ` statement. Then call the
5657:meth: `~BaseServer.handle_request ` or
5758:meth: `~BaseServer.serve_forever ` method of the server object to
5859process one or many requests. Finally, call :meth: `~BaseServer.server_close `
59- to close the socket.
60+ to close the socket (unless you used a :keyword: ` with ` statement) .
6061
6162When inheriting from :class: `ThreadingMixIn ` for threaded connection behavior,
6263you should explicitly declare how you want your threads to behave on an abrupt
@@ -353,6 +354,11 @@ Server Objects
353354 default implementation always returns :const: `True `.
354355
355356
357+ .. versionchanged :: 3.6
358+ Support for the :term: `context manager ` protocol was added. Exiting the
359+ context manager is equivalent to calling :meth: `server_close `.
360+
361+
356362Request Handler Objects
357363-----------------------
358364
@@ -433,11 +439,10 @@ This is the server side::
433439 HOST, PORT = "localhost", 9999
434440
435441 # Create the server, binding to localhost on port 9999
436- server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
437-
438- # Activate the server; this will keep running until you
439- # interrupt the program with Ctrl-C
440- server.serve_forever()
442+ with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
443+ # Activate the server; this will keep running until you
444+ # interrupt the program with Ctrl-C
445+ server.serve_forever()
441446
442447An alternative request handler class that makes use of streams (file-like
443448objects that simplify communication by providing the standard file interface)::
@@ -529,8 +534,8 @@ This is the server side::
529534
530535 if __name__ == "__main__":
531536 HOST, PORT = "localhost", 9999
532- server = socketserver.UDPServer((HOST, PORT), MyUDPHandler)
533- server.serve_forever()
537+ with socketserver.UDPServer((HOST, PORT), MyUDPHandler) as server:
538+ server.serve_forever()
534539
535540This is the client side::
536541
@@ -592,22 +597,22 @@ An example for the :class:`ThreadingMixIn` class::
592597 HOST, PORT = "localhost", 0
593598
594599 server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
595- ip, port = server.server_address
596-
597- # Start a thread with the server -- that thread will then start one
598- # more thread for each request
599- server_thread = threading.Thread(target=server.serve_forever)
600- # Exit the server thread when the main thread terminates
601- server_thread.daemon = True
602- server_thread.start()
603- print("Server loop running in thread:", server_thread.name )
604-
605- client(ip, port, "Hello World 1")
606- client(ip, port, "Hello World 2 ")
607- client(ip, port, "Hello World 3 ")
608-
609- server.shutdown()
610- server.server_close ()
600+ with server:
601+ ip, port = server.server_address
602+
603+ # Start a thread with the server -- that thread will then start one
604+ # more thread for each request
605+ server_thread = threading.Thread(target=server.serve_forever)
606+ # Exit the server thread when the main thread terminates
607+ server_thread.daemon = True
608+ server_thread.start( )
609+ print("Server loop running in thread:", server_thread.name)
610+
611+ client(ip, port, "Hello World 1 ")
612+ client(ip, port, "Hello World 2 ")
613+ client(ip, port, "Hello World 3")
614+
615+ server.shutdown ()
611616
612617
613618The output of the example should look something like this::
0 commit comments