Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(15)

Delta Between Two Patch Sets: Doc/library/socketserver.rst

Issue 26404: socketserver context manager
Left Patch Set: Created 4 years, 1 month ago
Right Patch Set: Created 4 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
1 :mod:`socketserver` --- A framework for network servers 1 :mod:`socketserver` --- A framework for network servers
2 ======================================================= 2 =======================================================
3 3
4 .. module:: socketserver 4 .. module:: socketserver
5 :synopsis: A framework for network servers. 5 :synopsis: A framework for network servers.
6 6
7 **Source code:** :source:`Lib/socketserver.py` 7 **Source code:** :source:`Lib/socketserver.py`
8 8
9 -------------- 9 --------------
10 10
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 or because it returns a lot of data which the client is slow to process. The 45 or because it returns a lot of data which the client is slow to process. The
46 solution is to create a separate process or thread to handle each request; the 46 solution is to create a separate process or thread to handle each request; the
47 :class:`ForkingMixIn` and :class:`ThreadingMixIn` mix-in classes can be used to 47 :class:`ForkingMixIn` and :class:`ThreadingMixIn` mix-in classes can be used to
48 support asynchronous behaviour. 48 support asynchronous behaviour.
49 49
50 Creating a server requires several steps. First, you must create a request 50 Creating a server requires several steps. First, you must create a request
51 handler class by subclassing the :class:`BaseRequestHandler` class and 51 handler class by subclassing the :class:`BaseRequestHandler` class and
52 overriding its :meth:`~BaseRequestHandler.handle` method; 52 overriding its :meth:`~BaseRequestHandler.handle` method;
53 this method will process incoming 53 this method will process incoming
54 requests. Second, you must instantiate one of the server classes, passing it 54 requests. Second, you must instantiate one of the server classes, passing it
55 the server's address and the request handler class. It is recommended to initiat e 55 the server's address and the request handler class. It is recommended to use
56 the class using :keyword:`with` statement. Then call the 56 the server in a :keyword:`with` statement. Then call the
57 :meth:`~BaseServer.handle_request` or 57 :meth:`~BaseServer.handle_request` or
58 :meth:`~BaseServer.serve_forever` method of the server object to 58 :meth:`~BaseServer.serve_forever` method of the server object to
59 process one or many requests. Finally, call :meth:`~BaseServer.server_close` 59 process one or many requests. Finally, call :meth:`~BaseServer.server_close`
60 to close the socket ( Unless you used the :keyword:`with` statement). 60 to close the socket (unless you used the :keyword:`with` statement).
Martin Panter 2016/02/22 11:57:06 The spacing here is a bit messed up
Martin Panter 2016/04/13 04:52:57 a “with” statement (matching ‘in a “with” statemen
61 61
62 When inheriting from :class:`ThreadingMixIn` for threaded connection behavior, 62 When inheriting from :class:`ThreadingMixIn` for threaded connection behavior,
63 you should explicitly declare how you want your threads to behave on an abrupt 63 you should explicitly declare how you want your threads to behave on an abrupt
64 shutdown. The :class:`ThreadingMixIn` class defines an attribute 64 shutdown. The :class:`ThreadingMixIn` class defines an attribute
65 *daemon_threads*, which indicates whether or not the server should wait for 65 *daemon_threads*, which indicates whether or not the server should wait for
66 thread termination. You should set the flag explicitly if you would like 66 thread termination. You should set the flag explicitly if you would like
67 threads to behave autonomously; the default is :const:`False`, meaning that 67 threads to behave autonomously; the default is :const:`False`, meaning that
68 Python will not exit until all threads created by :class:`ThreadingMixIn` have 68 Python will not exit until all threads created by :class:`ThreadingMixIn` have
69 exited. 69 exited.
70 70
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 347
348 348
349 .. method:: verify_request(request, client_address) 349 .. method:: verify_request(request, client_address)
350 350
351 Must return a Boolean value; if the value is :const:`True`, the request wi ll 351 Must return a Boolean value; if the value is :const:`True`, the request wi ll
352 be processed, and if it's :const:`False`, the request will be denied. Thi s 352 be processed, and if it's :const:`False`, the request will be denied. Thi s
353 function can be overridden to implement access controls for a server. The 353 function can be overridden to implement access controls for a server. The
354 default implementation always returns :const:`True`. 354 default implementation always returns :const:`True`.
355 355
356 356
357 .. versionadded:: 3.6 357 .. versionchanged:: 3.6
358 Support for the :term:`context manager` protocol was added. Exiting the 358 Support for the :term:`context manager` protocol was added. Exiting the
359 context manager is equivalent to calling :meth:`server_close`. 359 context manager is equivalent to calling :meth:`server_close`.
360 360
361 361
362 Request Handler Objects 362 Request Handler Objects
363 ----------------------- 363 -----------------------
364 364
365 .. class:: BaseRequestHandler 365 .. class:: BaseRequestHandler
366 366
367 This is the superclass of all request handler objects. It defines 367 This is the superclass of all request handler objects. It defines
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 print("{} wrote:".format(self.client_address[0])) 433 print("{} wrote:".format(self.client_address[0]))
434 print(self.data) 434 print(self.data)
435 # just send back the same data, but upper-cased 435 # just send back the same data, but upper-cased
436 self.request.sendall(self.data.upper()) 436 self.request.sendall(self.data.upper())
437 437
438 if __name__ == "__main__": 438 if __name__ == "__main__":
439 HOST, PORT = "localhost", 9999 439 HOST, PORT = "localhost", 9999
440 440
441 # Create the server, binding to localhost on port 9999 441 # Create the server, binding to localhost on port 9999
442 with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server: 442 with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
443
Martin Panter 2016/02/22 11:57:06 Would this look better without the blank line?
444 # Activate the server; this will keep running until you 443 # Activate the server; this will keep running until you
445 # interrupt the program with Ctrl-C 444 # interrupt the program with Ctrl-C
446 server.serve_forever() 445 server.serve_forever()
447 446
448 An alternative request handler class that makes use of streams (file-like 447 An alternative request handler class that makes use of streams (file-like
449 objects that simplify communication by providing the standard file interface):: 448 objects that simplify communication by providing the standard file interface)::
450 449
451 class MyTCPHandler(socketserver.StreamRequestHandler): 450 class MyTCPHandler(socketserver.StreamRequestHandler):
452 451
453 def handle(self): 452 def handle(self):
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 sock.sendall(bytes(message, 'ascii')) 589 sock.sendall(bytes(message, 'ascii'))
591 response = str(sock.recv(1024), 'ascii') 590 response = str(sock.recv(1024), 'ascii')
592 print("Received: {}".format(response)) 591 print("Received: {}".format(response))
593 finally: 592 finally:
594 sock.close() 593 sock.close()
595 594
596 if __name__ == "__main__": 595 if __name__ == "__main__":
597 # Port 0 means to select an arbitrary unused port 596 # Port 0 means to select an arbitrary unused port
598 HOST, PORT = "localhost", 0 597 HOST, PORT = "localhost", 0
599 598
600 with ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler) as server : 599 with ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler) as server :
Martin Panter 2016/04/13 04:52:57 Split this into two lines to limit the width
601 ip, port = server.server_address 600 ip, port = server.server_address
602 601
603 # Start a thread with the server -- that thread will then start one 602 # Start a thread with the server -- that thread will then start one
604 # more thread for each request 603 # more thread for each request
605 server_thread = threading.Thread(target=server.serve_forever) 604 server_thread = threading.Thread(target=server.serve_forever)
606 # Exit the server thread when the main thread terminates 605 # Exit the server thread when the main thread terminates
607 server_thread.daemon = True 606 server_thread.daemon = True
608 server_thread.start() 607 server_thread.start()
609 print("Server loop running in thread:", server_thread.name) 608 print("Server loop running in thread:", server_thread.name)
610 609
611 client(ip, port, "Hello World 1") 610 client(ip, port, "Hello World 1")
612 client(ip, port, "Hello World 2") 611 client(ip, port, "Hello World 2")
613 client(ip, port, "Hello World 3") 612 client(ip, port, "Hello World 3")
614 613
615 server.shutdown() 614 server.shutdown()
616 615
617 616
618 The output of the example should look something like this:: 617 The output of the example should look something like this::
619 618
620 $ python ThreadedTCPServer.py 619 $ python ThreadedTCPServer.py
621 Server loop running in thread: Thread-1 620 Server loop running in thread: Thread-1
622 Received: Thread-2: Hello World 1 621 Received: Thread-2: Hello World 1
623 Received: Thread-3: Hello World 2 622 Received: Thread-3: Hello World 2
624 Received: Thread-4: Hello World 3 623 Received: Thread-4: Hello World 3
625 624
626 625
627 The :class:`ForkingMixIn` class is used in the same way, except that the server 626 The :class:`ForkingMixIn` class is used in the same way, except that the server
628 will spawn a new process for each request. 627 will spawn a new process for each request.
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+