@@ -436,11 +436,11 @@ coroutine with ``yield from``. For example, the :meth:`StreamWriter.drain`
436436coroutine 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
445445TCP 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
473473running loop. At :meth: `~BaseEventLoop.run_until_complete ` exit, the loop is
474474no 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
479479TCP 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::
511511methods are asynchronous. ``yield from `` is not needed because these transport
512512methods 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.
0 commit comments