Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 04e6df3

Browse files
committed
asyncio doc: add examples showing the 3 ways to wait for data from an open
socket
1 parent 6888b96 commit 04e6df3

3 files changed

Lines changed: 168 additions & 10 deletions

File tree

Doc/library/asyncio-eventloop.rst

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,10 @@ On Windows with :class:`ProactorEventLoop`, these methods are not supported.
339339

340340
Stop watching the file descriptor for write availability.
341341

342+
The :ref:`watch a file descriptor for read events <asyncio-watch-read-event>`
343+
example uses the low-level :meth:`BaseEventLoop.add_reader` method to register
344+
the file descriptor of a socket.
345+
342346

343347
Low-level socket operations
344348
---------------------------
@@ -663,10 +667,59 @@ Print ``"Hello World"`` every two seconds using a callback scheduled by the
663667
uses a :ref:`coroutine <coroutine>`.
664668

665669

666-
Example: Set signal handlers for SIGINT and SIGTERM
667-
---------------------------------------------------
670+
.. _asyncio-watch-read-event:
671+
672+
Watch a file descriptor for read events
673+
---------------------------------------
674+
675+
Wait until a file descriptor received some data using the
676+
:meth:`BaseEventLoop.add_reader` method and then close the event loop::
677+
678+
import asyncio
679+
import socket
680+
681+
# Create a pair of connected file descriptors
682+
rsock, wsock = socket.socketpair()
683+
loop = asyncio.get_event_loop()
684+
685+
def reader():
686+
data = rsock.recv(100)
687+
print("Received:", data.decode())
688+
# We are done: unregister the register
689+
loop.remove_reader(rsock)
690+
# Stop the event loop
691+
loop.stop()
692+
693+
# Wait for read event
694+
loop.add_reader(rsock, reader)
695+
696+
# Simulate the reception of data from the network
697+
loop.call_soon(wsock.send, 'abc'.encode())
698+
699+
# Run the event loop
700+
loop.run_forever()
701+
702+
# We are done, close sockets and the event loop
703+
rsock.close()
704+
wsock.close()
705+
loop.close()
706+
707+
.. seealso::
708+
709+
The :ref:`register an open socket to wait for data using a protocol
710+
<asyncio-register-socket>` example uses a low-level protocol created by the
711+
:meth:`BaseEventLoop.create_connection` method.
712+
713+
The :ref:`register an open socket to wait for data using streams
714+
<asyncio-register-socket-streams>` example uses high-level streams
715+
created by the :func:`open_connection` function in a coroutine.
716+
668717

669-
Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM`::
718+
Set signal handlers for SIGINT and SIGTERM
719+
------------------------------------------
720+
721+
Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM` using
722+
the :meth:`BaseEventLoop.add_signal_handler` method::
670723

671724
import asyncio
672725
import functools
@@ -688,4 +741,3 @@ Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM`::
688741
loop.run_forever()
689742
finally:
690743
loop.close()
691-

Doc/library/asyncio-protocol.rst

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -436,11 +436,11 @@ coroutine with ``yield from``. For example, the :meth:`StreamWriter.drain`
436436
coroutine can be used to wait until the write buffer is flushed.
437437

438438

439-
Protocol example: TCP echo server and client
440-
============================================
439+
Protocol examples
440+
=================
441441

442-
Echo client
443-
-----------
442+
TCP echo client
443+
---------------
444444

445445
TCP echo client example, send data and wait until the connection is closed::
446446

@@ -473,8 +473,8 @@ having to write a short coroutine to handle the exception and stop the
473473
running loop. At :meth:`~BaseEventLoop.run_until_complete` exit, the loop is
474474
no longer running, so there is no need to stop the loop in case of an error.
475475

476-
Echo server
477-
-----------
476+
TCP echo server
477+
---------------
478478

479479
TCP echo server example, send back received data and close the connection::
480480

@@ -511,4 +511,60 @@ TCP echo server example, send back received data and close the connection::
511511
methods are asynchronous. ``yield from`` is not needed because these transport
512512
methods are not coroutines.
513513

514+
.. _asyncio-register-socket:
514515

516+
Register an open socket to wait for data using a protocol
517+
---------------------------------------------------------
518+
519+
Wait until a socket receives data using the
520+
:meth:`BaseEventLoop.create_connection` method with a protocol, and then close
521+
the event loop ::
522+
523+
import asyncio
524+
import socket
525+
526+
# Create a pair of connected sockets
527+
rsock, wsock = socket.socketpair()
528+
loop = asyncio.get_event_loop()
529+
530+
class MyProtocol(asyncio.Protocol):
531+
transport = None
532+
533+
def connection_made(self, transport):
534+
self.transport = transport
535+
536+
def data_received(self, data):
537+
print("Received:", data.decode())
538+
539+
# We are done: close the transport (it will call connection_lost())
540+
self.transport.close()
541+
542+
def connection_lost(self, exc):
543+
# The socket has been closed, stop the event loop
544+
loop.stop()
545+
546+
# Register the socket to wait for data
547+
connect_coro = loop.create_connection(MyProtocol, sock=rsock)
548+
transport, protocol = loop.run_until_complete(connect_coro)
549+
550+
# Simulate the reception of data from the network
551+
loop.call_soon(wsock.send, 'abc'.encode())
552+
553+
# Run the event loop
554+
loop.run_forever()
555+
556+
# We are done, close sockets and the event loop
557+
rsock.close()
558+
wsock.close()
559+
loop.close()
560+
561+
.. seealso::
562+
563+
The :ref:`watch a file descriptor for read events
564+
<asyncio-watch-read-event>` example uses the low-level
565+
:meth:`BaseEventLoop.add_reader` method to register the file descriptor of a
566+
socket.
567+
568+
The :ref:`register an open socket to wait for data using streams
569+
<asyncio-register-socket-streams>` example uses high-level streams
570+
created by the :func:`open_connection` function in a coroutine.

Doc/library/asyncio-stream.rst

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,53 @@ Usage::
283283

284284
python example.py http://example.com/path/page.html
285285

286+
or with HTTPS::
287+
288+
python example.py https://example.com/path/page.html
289+
290+
.. _asyncio-register-socket-streams:
291+
292+
Register an open socket to wait for data using streams
293+
------------------------------------------------------
294+
295+
Coroutine waiting until a socket receives data using the
296+
:func:`open_connection` function::
297+
298+
import asyncio
299+
import socket
300+
301+
def wait_for_data(loop):
302+
# Create a pair of connected sockets
303+
rsock, wsock = socket.socketpair()
304+
305+
# Register the open socket to wait for data
306+
reader, writer = yield from asyncio.open_connection(sock=rsock, loop=loop)
307+
308+
# Simulate the reception of data from the network
309+
loop.call_soon(wsock.send, 'abc'.encode())
310+
311+
# Wait for data
312+
data = yield from reader.read(100)
313+
314+
# Got data, we are done: close the socket
315+
print("Received:", data.decode())
316+
writer.close()
317+
318+
# Close the second socket
319+
wsock.close()
320+
321+
loop = asyncio.get_event_loop()
322+
loop.run_until_complete(wait_for_data(loop))
323+
loop.close()
324+
325+
.. seealso::
326+
327+
The :ref:`register an open socket to wait for data using a protocol
328+
<asyncio-register-socket>` example uses a low-level protocol created by the
329+
:meth:`BaseEventLoop.create_connection` method.
330+
331+
The :ref:`watch a file descriptor for read events
332+
<asyncio-watch-read-event>` example uses the low-level
333+
:meth:`BaseEventLoop.add_reader` method to register the file descriptor of a
334+
socket.
335+

0 commit comments

Comments
 (0)