summaryrefslogtreecommitdiffstats
path: root/Doc/library
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2014-10-11 14:16:27 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2014-10-11 14:16:27 (GMT)
commit04e6df330ddbec28cbbcba0f36235040e267692d (patch)
treea5ace7b5a2966b84b74fcdc5cecee7398197c350 /Doc/library
parent6888b96cee44364f5414b0e4dbfc69dba8b639b4 (diff)
downloadcpython-04e6df330ddbec28cbbcba0f36235040e267692d.zip
cpython-04e6df330ddbec28cbbcba0f36235040e267692d.tar.gz
cpython-04e6df330ddbec28cbbcba0f36235040e267692d.tar.bz2
asyncio doc: add examples showing the 3 ways to wait for data from an open
socket
Diffstat (limited to 'Doc/library')
-rw-r--r--Doc/library/asyncio-eventloop.rst60
-rw-r--r--Doc/library/asyncio-protocol.rst68
-rw-r--r--Doc/library/asyncio-stream.rst50
3 files changed, 168 insertions, 10 deletions
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst
index ed38512..59682d3 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -339,6 +339,10 @@ On Windows with :class:`ProactorEventLoop`, these methods are not supported.
Stop watching the file descriptor for write availability.
+The :ref:`watch a file descriptor for read events <asyncio-watch-read-event>`
+example uses the low-level :meth:`BaseEventLoop.add_reader` method to register
+the file descriptor of a socket.
+
Low-level socket operations
---------------------------
@@ -663,10 +667,59 @@ Print ``"Hello World"`` every two seconds using a callback scheduled by the
uses a :ref:`coroutine <coroutine>`.
-Example: Set signal handlers for SIGINT and SIGTERM
----------------------------------------------------
+.. _asyncio-watch-read-event:
+
+Watch a file descriptor for read events
+---------------------------------------
+
+Wait until a file descriptor received some data using the
+:meth:`BaseEventLoop.add_reader` method and then close the event loop::
+
+ import asyncio
+ import socket
+
+ # Create a pair of connected file descriptors
+ rsock, wsock = socket.socketpair()
+ loop = asyncio.get_event_loop()
+
+ def reader():
+ data = rsock.recv(100)
+ print("Received:", data.decode())
+ # We are done: unregister the register
+ loop.remove_reader(rsock)
+ # Stop the event loop
+ loop.stop()
+
+ # Wait for read event
+ loop.add_reader(rsock, reader)
+
+ # Simulate the reception of data from the network
+ loop.call_soon(wsock.send, 'abc'.encode())
+
+ # Run the event loop
+ loop.run_forever()
+
+ # We are done, close sockets and the event loop
+ rsock.close()
+ wsock.close()
+ loop.close()
+
+.. seealso::
+
+ The :ref:`register an open socket to wait for data using a protocol
+ <asyncio-register-socket>` example uses a low-level protocol created by the
+ :meth:`BaseEventLoop.create_connection` method.
+
+ The :ref:`register an open socket to wait for data using streams
+ <asyncio-register-socket-streams>` example uses high-level streams
+ created by the :func:`open_connection` function in a coroutine.
+
-Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM`::
+Set signal handlers for SIGINT and SIGTERM
+------------------------------------------
+
+Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM` using
+the :meth:`BaseEventLoop.add_signal_handler` method::
import asyncio
import functools
@@ -688,4 +741,3 @@ Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM`::
loop.run_forever()
finally:
loop.close()
-
diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst
index 92b055a..3fa2f3e 100644
--- a/Doc/library/asyncio-protocol.rst
+++ b/Doc/library/asyncio-protocol.rst
@@ -436,11 +436,11 @@ coroutine with ``yield from``. For example, the :meth:`StreamWriter.drain`
coroutine can be used to wait until the write buffer is flushed.
-Protocol example: TCP echo server and client
-============================================
+Protocol examples
+=================
-Echo client
------------
+TCP echo client
+---------------
TCP echo client example, send data and wait until the connection is closed::
@@ -473,8 +473,8 @@ having to write a short coroutine to handle the exception and stop the
running loop. At :meth:`~BaseEventLoop.run_until_complete` exit, the loop is
no longer running, so there is no need to stop the loop in case of an error.
-Echo server
------------
+TCP echo server
+---------------
TCP echo server example, send back received data and close the connection::
@@ -511,4 +511,60 @@ TCP echo server example, send back received data and close the connection::
methods are asynchronous. ``yield from`` is not needed because these transport
methods are not coroutines.
+.. _asyncio-register-socket:
+Register an open socket to wait for data using a protocol
+---------------------------------------------------------
+
+Wait until a socket receives data using the
+:meth:`BaseEventLoop.create_connection` method with a protocol, and then close
+the event loop ::
+
+ import asyncio
+ import socket
+
+ # Create a pair of connected sockets
+ rsock, wsock = socket.socketpair()
+ loop = asyncio.get_event_loop()
+
+ class MyProtocol(asyncio.Protocol):
+ transport = None
+
+ def connection_made(self, transport):
+ self.transport = transport
+
+ def data_received(self, data):
+ print("Received:", data.decode())
+
+ # We are done: close the transport (it will call connection_lost())
+ self.transport.close()
+
+ def connection_lost(self, exc):
+ # The socket has been closed, stop the event loop
+ loop.stop()
+
+ # Register the socket to wait for data
+ connect_coro = loop.create_connection(MyProtocol, sock=rsock)
+ transport, protocol = loop.run_until_complete(connect_coro)
+
+ # Simulate the reception of data from the network
+ loop.call_soon(wsock.send, 'abc'.encode())
+
+ # Run the event loop
+ loop.run_forever()
+
+ # We are done, close sockets and the event loop
+ rsock.close()
+ wsock.close()
+ loop.close()
+
+.. seealso::
+
+ The :ref:`watch a file descriptor for read events
+ <asyncio-watch-read-event>` example uses the low-level
+ :meth:`BaseEventLoop.add_reader` method to register the file descriptor of a
+ socket.
+
+ The :ref:`register an open socket to wait for data using streams
+ <asyncio-register-socket-streams>` example uses high-level streams
+ created by the :func:`open_connection` function in a coroutine.
diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst
index 19ec935..9db2380 100644
--- a/Doc/library/asyncio-stream.rst
+++ b/Doc/library/asyncio-stream.rst
@@ -283,3 +283,53 @@ Usage::
python example.py http://example.com/path/page.html
+or with HTTPS::
+
+ python example.py https://example.com/path/page.html
+
+.. _asyncio-register-socket-streams:
+
+Register an open socket to wait for data using streams
+------------------------------------------------------
+
+Coroutine waiting until a socket receives data using the
+:func:`open_connection` function::
+
+ import asyncio
+ import socket
+
+ def wait_for_data(loop):
+ # Create a pair of connected sockets
+ rsock, wsock = socket.socketpair()
+
+ # Register the open socket to wait for data
+ reader, writer = yield from asyncio.open_connection(sock=rsock, loop=loop)
+
+ # Simulate the reception of data from the network
+ loop.call_soon(wsock.send, 'abc'.encode())
+
+ # Wait for data
+ data = yield from reader.read(100)
+
+ # Got data, we are done: close the socket
+ print("Received:", data.decode())
+ writer.close()
+
+ # Close the second socket
+ wsock.close()
+
+ loop = asyncio.get_event_loop()
+ loop.run_until_complete(wait_for_data(loop))
+ loop.close()
+
+.. seealso::
+
+ The :ref:`register an open socket to wait for data using a protocol
+ <asyncio-register-socket>` example uses a low-level protocol created by the
+ :meth:`BaseEventLoop.create_connection` method.
+
+ The :ref:`watch a file descriptor for read events
+ <asyncio-watch-read-event>` example uses the low-level
+ :meth:`BaseEventLoop.add_reader` method to register the file descriptor of a
+ socket.
+