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

Side by Side Diff: Doc/library/socketserver.rst

Issue 26404: socketserver context manager
Patch Set: Created 4 years 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:
View unified diff | Download patch
« no previous file with comments | « no previous file | Lib/socketserver.py » ('j') | Lib/test/test_socketserver.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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. Then call the 55 the server's address and the request handler class. It is recommended to initiat e
56 the class using :keyword:`with` statement. Then call the
56 :meth:`~BaseServer.handle_request` or 57 :meth:`~BaseServer.handle_request` or
57 :meth:`~BaseServer.serve_forever` method of the server object to 58 :meth:`~BaseServer.serve_forever` method of the server object to
58 process one or many requests. Finally, call :meth:`~BaseServer.server_close` 59 process one or many requests. Finally, call :meth:`~BaseServer.server_close`
59 to close the socket. 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
60 61
61 When inheriting from :class:`ThreadingMixIn` for threaded connection behavior, 62 When inheriting from :class:`ThreadingMixIn` for threaded connection behavior,
62 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
63 shutdown. The :class:`ThreadingMixIn` class defines an attribute 64 shutdown. The :class:`ThreadingMixIn` class defines an attribute
64 *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
65 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
66 threads to behave autonomously; the default is :const:`False`, meaning that 67 threads to behave autonomously; the default is :const:`False`, meaning that
67 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
68 exited. 69 exited.
69 70
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 Called by the server's constructor to bind the socket to the desired addre ss. 345 Called by the server's constructor to bind the socket to the desired addre ss.
345 May be overridden. 346 May be overridden.
346 347
347 348
348 .. method:: verify_request(request, client_address) 349 .. method:: verify_request(request, client_address)
349 350
350 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
351 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
352 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
353 default implementation always returns :const:`True`. 354 default implementation always returns :const:`True`.
355
356
357 .. versionadded:: 3.6
358 Support for the :term:`context manager` protocol was added. Exiting the
359 context manager is equivalent to calling :meth:`server_close`.
354 360
355 361
356 Request Handler Objects 362 Request Handler Objects
357 ----------------------- 363 -----------------------
358 364
359 .. class:: BaseRequestHandler 365 .. class:: BaseRequestHandler
360 366
361 This is the superclass of all request handler objects. It defines 367 This is the superclass of all request handler objects. It defines
362 the interface, given below. A concrete request handler subclass must 368 the interface, given below. A concrete request handler subclass must
363 define a new :meth:`handle` method, and can override any of 369 define a new :meth:`handle` method, and can override any of
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 self.data = self.request.recv(1024).strip() 432 self.data = self.request.recv(1024).strip()
427 print("{} wrote:".format(self.client_address[0])) 433 print("{} wrote:".format(self.client_address[0]))
428 print(self.data) 434 print(self.data)
429 # just send back the same data, but upper-cased 435 # just send back the same data, but upper-cased
430 self.request.sendall(self.data.upper()) 436 self.request.sendall(self.data.upper())
431 437
432 if __name__ == "__main__": 438 if __name__ == "__main__":
433 HOST, PORT = "localhost", 9999 439 HOST, PORT = "localhost", 9999
434 440
435 # Create the server, binding to localhost on port 9999 441 # Create the server, binding to localhost on port 9999
436 server = socketserver.TCPServer((HOST, PORT), MyTCPHandler) 442 with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
437 443
Martin Panter 2016/02/22 11:57:06 Would this look better without the blank line?
438 # Activate the server; this will keep running until you 444 # Activate the server; this will keep running until you
439 # interrupt the program with Ctrl-C 445 # interrupt the program with Ctrl-C
440 server.serve_forever() 446 server.serve_forever()
441 447
442 An alternative request handler class that makes use of streams (file-like 448 An alternative request handler class that makes use of streams (file-like
443 objects that simplify communication by providing the standard file interface):: 449 objects that simplify communication by providing the standard file interface)::
444 450
445 class MyTCPHandler(socketserver.StreamRequestHandler): 451 class MyTCPHandler(socketserver.StreamRequestHandler):
446 452
447 def handle(self): 453 def handle(self):
448 # self.rfile is a file-like object created by the handler; 454 # self.rfile is a file-like object created by the handler;
449 # we can now use e.g. readline() instead of raw recv() calls 455 # we can now use e.g. readline() instead of raw recv() calls
450 self.data = self.rfile.readline().strip() 456 self.data = self.rfile.readline().strip()
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 528
523 def handle(self): 529 def handle(self):
524 data = self.request[0].strip() 530 data = self.request[0].strip()
525 socket = self.request[1] 531 socket = self.request[1]
526 print("{} wrote:".format(self.client_address[0])) 532 print("{} wrote:".format(self.client_address[0]))
527 print(data) 533 print(data)
528 socket.sendto(data.upper(), self.client_address) 534 socket.sendto(data.upper(), self.client_address)
529 535
530 if __name__ == "__main__": 536 if __name__ == "__main__":
531 HOST, PORT = "localhost", 9999 537 HOST, PORT = "localhost", 9999
532 server = socketserver.UDPServer((HOST, PORT), MyUDPHandler) 538 with socketserver.UDPServer((HOST, PORT), MyUDPHandler) as server:
533 server.serve_forever() 539 server.serve_forever()
534 540
535 This is the client side:: 541 This is the client side::
536 542
537 import socket 543 import socket
538 import sys 544 import sys
539 545
540 HOST, PORT = "localhost", 9999 546 HOST, PORT = "localhost", 9999
541 data = " ".join(sys.argv[1:]) 547 data = " ".join(sys.argv[1:])
542 548
543 # SOCK_DGRAM is the socket type to use for UDP sockets 549 # SOCK_DGRAM is the socket type to use for UDP sockets
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 sock.sendall(bytes(message, 'ascii')) 590 sock.sendall(bytes(message, 'ascii'))
585 response = str(sock.recv(1024), 'ascii') 591 response = str(sock.recv(1024), 'ascii')
586 print("Received: {}".format(response)) 592 print("Received: {}".format(response))
587 finally: 593 finally:
588 sock.close() 594 sock.close()
589 595
590 if __name__ == "__main__": 596 if __name__ == "__main__":
591 # Port 0 means to select an arbitrary unused port 597 # Port 0 means to select an arbitrary unused port
592 HOST, PORT = "localhost", 0 598 HOST, PORT = "localhost", 0
593 599
594 server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler) 600 with ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler) as server :
595 ip, port = server.server_address 601 ip, port = server.server_address
596 602
597 # Start a thread with the server -- that thread will then start one 603 # Start a thread with the server -- that thread will then start one
598 # more thread for each request 604 # more thread for each request
599 server_thread = threading.Thread(target=server.serve_forever) 605 server_thread = threading.Thread(target=server.serve_forever)
600 # Exit the server thread when the main thread terminates 606 # Exit the server thread when the main thread terminates
601 server_thread.daemon = True 607 server_thread.daemon = True
602 server_thread.start() 608 server_thread.start()
603 print("Server loop running in thread:", server_thread.name) 609 print("Server loop running in thread:", server_thread.name)
604 610
605 client(ip, port, "Hello World 1") 611 client(ip, port, "Hello World 1")
606 client(ip, port, "Hello World 2") 612 client(ip, port, "Hello World 2")
607 client(ip, port, "Hello World 3") 613 client(ip, port, "Hello World 3")
608 614
609 server.shutdown() 615 server.shutdown()
610 server.server_close()
611 616
612 617
613 The output of the example should look something like this:: 618 The output of the example should look something like this::
614 619
615 $ python ThreadedTCPServer.py 620 $ python ThreadedTCPServer.py
616 Server loop running in thread: Thread-1 621 Server loop running in thread: Thread-1
617 Received: Thread-2: Hello World 1 622 Received: Thread-2: Hello World 1
618 Received: Thread-3: Hello World 2 623 Received: Thread-3: Hello World 2
619 Received: Thread-4: Hello World 3 624 Received: Thread-4: Hello World 3
620 625
621 626
622 The :class:`ForkingMixIn` class is used in the same way, except that the server 627 The :class:`ForkingMixIn` class is used in the same way, except that the server
623 will spawn a new process for each request. 628 will spawn a new process for each request.
OLDNEW
« no previous file with comments | « no previous file | Lib/socketserver.py » ('j') | Lib/test/test_socketserver.py » ('J')

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