17db96d56Sopenharmony_ci.. currentmodule:: asyncio
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci.. _asyncio-transports-protocols:
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci========================
87db96d56Sopenharmony_ciTransports and Protocols
97db96d56Sopenharmony_ci========================
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci.. rubric:: Preface
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ciTransports and Protocols are used by the **low-level** event loop
147db96d56Sopenharmony_ciAPIs such as :meth:`loop.create_connection`.  They use
157db96d56Sopenharmony_cicallback-based programming style and enable high-performance
167db96d56Sopenharmony_ciimplementations of network or IPC protocols (e.g. HTTP).
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ciEssentially, transports and protocols should only be used in
197db96d56Sopenharmony_cilibraries and frameworks and never in high-level asyncio
207db96d56Sopenharmony_ciapplications.
217db96d56Sopenharmony_ci
227db96d56Sopenharmony_ciThis documentation page covers both `Transports`_ and `Protocols`_.
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_ci.. rubric:: Introduction
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ciAt the highest level, the transport is concerned with *how* bytes
277db96d56Sopenharmony_ciare transmitted, while the protocol determines *which* bytes to
287db96d56Sopenharmony_citransmit (and to some extent when).
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ciA different way of saying the same thing: a transport is an
317db96d56Sopenharmony_ciabstraction for a socket (or similar I/O endpoint) while a protocol
327db96d56Sopenharmony_ciis an abstraction for an application, from the transport's point
337db96d56Sopenharmony_ciof view.
347db96d56Sopenharmony_ci
357db96d56Sopenharmony_ciYet another view is the transport and protocol interfaces
367db96d56Sopenharmony_citogether define an abstract interface for using network I/O and
377db96d56Sopenharmony_ciinterprocess I/O.
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ciThere is always a 1:1 relationship between transport and protocol
407db96d56Sopenharmony_ciobjects: the protocol calls transport methods to send data,
417db96d56Sopenharmony_ciwhile the transport calls protocol methods to pass it data that
427db96d56Sopenharmony_cihas been received.
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ciMost of connection oriented event loop methods
457db96d56Sopenharmony_ci(such as :meth:`loop.create_connection`) usually accept a
467db96d56Sopenharmony_ci*protocol_factory* argument used to create a *Protocol* object
477db96d56Sopenharmony_cifor an accepted connection, represented by a *Transport* object.
487db96d56Sopenharmony_ciSuch methods usually return a tuple of ``(transport, protocol)``.
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_ci.. rubric:: Contents
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ciThis documentation page contains the following sections:
537db96d56Sopenharmony_ci
547db96d56Sopenharmony_ci* The `Transports`_ section documents asyncio :class:`BaseTransport`,
557db96d56Sopenharmony_ci  :class:`ReadTransport`, :class:`WriteTransport`, :class:`Transport`,
567db96d56Sopenharmony_ci  :class:`DatagramTransport`, and :class:`SubprocessTransport`
577db96d56Sopenharmony_ci  classes.
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_ci* The `Protocols`_ section documents asyncio :class:`BaseProtocol`,
607db96d56Sopenharmony_ci  :class:`Protocol`, :class:`BufferedProtocol`,
617db96d56Sopenharmony_ci  :class:`DatagramProtocol`, and :class:`SubprocessProtocol` classes.
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci* The `Examples`_ section showcases how to work with transports,
647db96d56Sopenharmony_ci  protocols, and low-level event loop APIs.
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci.. _asyncio-transport:
687db96d56Sopenharmony_ci
697db96d56Sopenharmony_ciTransports
707db96d56Sopenharmony_ci==========
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ci**Source code:** :source:`Lib/asyncio/transports.py`
737db96d56Sopenharmony_ci
747db96d56Sopenharmony_ci----------------------------------------------------
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ciTransports are classes provided by :mod:`asyncio` in order to abstract
777db96d56Sopenharmony_civarious kinds of communication channels.
787db96d56Sopenharmony_ci
797db96d56Sopenharmony_ciTransport objects are always instantiated by an
807db96d56Sopenharmony_ci:ref:`asyncio event loop <asyncio-event-loop>`.
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_ciasyncio implements transports for TCP, UDP, SSL, and subprocess pipes.
837db96d56Sopenharmony_ciThe methods available on a transport depend on the transport's kind.
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_ciThe transport classes are :ref:`not thread safe <asyncio-multithreading>`.
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_ciTransports Hierarchy
897db96d56Sopenharmony_ci--------------------
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_ci.. class:: BaseTransport
927db96d56Sopenharmony_ci
937db96d56Sopenharmony_ci   Base class for all transports.  Contains methods that all
947db96d56Sopenharmony_ci   asyncio transports share.
957db96d56Sopenharmony_ci
967db96d56Sopenharmony_ci.. class:: WriteTransport(BaseTransport)
977db96d56Sopenharmony_ci
987db96d56Sopenharmony_ci   A base transport for write-only connections.
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_ci   Instances of the *WriteTransport* class are returned from
1017db96d56Sopenharmony_ci   the :meth:`loop.connect_write_pipe` event loop method and
1027db96d56Sopenharmony_ci   are also used by subprocess-related methods like
1037db96d56Sopenharmony_ci   :meth:`loop.subprocess_exec`.
1047db96d56Sopenharmony_ci
1057db96d56Sopenharmony_ci.. class:: ReadTransport(BaseTransport)
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ci   A base transport for read-only connections.
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_ci   Instances of the *ReadTransport* class are returned from
1107db96d56Sopenharmony_ci   the :meth:`loop.connect_read_pipe` event loop method and
1117db96d56Sopenharmony_ci   are also used by subprocess-related methods like
1127db96d56Sopenharmony_ci   :meth:`loop.subprocess_exec`.
1137db96d56Sopenharmony_ci
1147db96d56Sopenharmony_ci.. class:: Transport(WriteTransport, ReadTransport)
1157db96d56Sopenharmony_ci
1167db96d56Sopenharmony_ci   Interface representing a bidirectional transport, such as a
1177db96d56Sopenharmony_ci   TCP connection.
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci   The user does not instantiate a transport directly; they call a
1207db96d56Sopenharmony_ci   utility function, passing it a protocol factory and other
1217db96d56Sopenharmony_ci   information necessary to create the transport and protocol.
1227db96d56Sopenharmony_ci
1237db96d56Sopenharmony_ci   Instances of the *Transport* class are returned from or used by
1247db96d56Sopenharmony_ci   event loop methods like :meth:`loop.create_connection`,
1257db96d56Sopenharmony_ci   :meth:`loop.create_unix_connection`,
1267db96d56Sopenharmony_ci   :meth:`loop.create_server`, :meth:`loop.sendfile`, etc.
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_ci
1297db96d56Sopenharmony_ci.. class:: DatagramTransport(BaseTransport)
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci   A transport for datagram (UDP) connections.
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_ci   Instances of the *DatagramTransport* class are returned from
1347db96d56Sopenharmony_ci   the :meth:`loop.create_datagram_endpoint` event loop method.
1357db96d56Sopenharmony_ci
1367db96d56Sopenharmony_ci
1377db96d56Sopenharmony_ci.. class:: SubprocessTransport(BaseTransport)
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_ci   An abstraction to represent a connection between a parent and its
1407db96d56Sopenharmony_ci   child OS process.
1417db96d56Sopenharmony_ci
1427db96d56Sopenharmony_ci   Instances of the *SubprocessTransport* class are returned from
1437db96d56Sopenharmony_ci   event loop methods :meth:`loop.subprocess_shell` and
1447db96d56Sopenharmony_ci   :meth:`loop.subprocess_exec`.
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ciBase Transport
1487db96d56Sopenharmony_ci--------------
1497db96d56Sopenharmony_ci
1507db96d56Sopenharmony_ci.. method:: BaseTransport.close()
1517db96d56Sopenharmony_ci
1527db96d56Sopenharmony_ci   Close the transport.
1537db96d56Sopenharmony_ci
1547db96d56Sopenharmony_ci   If the transport has a buffer for outgoing
1557db96d56Sopenharmony_ci   data, buffered data will be flushed asynchronously.  No more data
1567db96d56Sopenharmony_ci   will be received.  After all buffered data is flushed, the
1577db96d56Sopenharmony_ci   protocol's :meth:`protocol.connection_lost()
1587db96d56Sopenharmony_ci   <BaseProtocol.connection_lost>` method will be called with
1597db96d56Sopenharmony_ci   :const:`None` as its argument. The transport should not be
1607db96d56Sopenharmony_ci   used once it is closed.
1617db96d56Sopenharmony_ci
1627db96d56Sopenharmony_ci.. method:: BaseTransport.is_closing()
1637db96d56Sopenharmony_ci
1647db96d56Sopenharmony_ci   Return ``True`` if the transport is closing or is closed.
1657db96d56Sopenharmony_ci
1667db96d56Sopenharmony_ci.. method:: BaseTransport.get_extra_info(name, default=None)
1677db96d56Sopenharmony_ci
1687db96d56Sopenharmony_ci   Return information about the transport or underlying resources
1697db96d56Sopenharmony_ci   it uses.
1707db96d56Sopenharmony_ci
1717db96d56Sopenharmony_ci   *name* is a string representing the piece of transport-specific
1727db96d56Sopenharmony_ci   information to get.
1737db96d56Sopenharmony_ci
1747db96d56Sopenharmony_ci   *default* is the value to return if the information is not
1757db96d56Sopenharmony_ci   available, or if the transport does not support querying it
1767db96d56Sopenharmony_ci   with the given third-party event loop implementation or on the
1777db96d56Sopenharmony_ci   current platform.
1787db96d56Sopenharmony_ci
1797db96d56Sopenharmony_ci   For example, the following code attempts to get the underlying
1807db96d56Sopenharmony_ci   socket object of the transport::
1817db96d56Sopenharmony_ci
1827db96d56Sopenharmony_ci      sock = transport.get_extra_info('socket')
1837db96d56Sopenharmony_ci      if sock is not None:
1847db96d56Sopenharmony_ci          print(sock.getsockopt(...))
1857db96d56Sopenharmony_ci
1867db96d56Sopenharmony_ci   Categories of information that can be queried on some transports:
1877db96d56Sopenharmony_ci
1887db96d56Sopenharmony_ci   * socket:
1897db96d56Sopenharmony_ci
1907db96d56Sopenharmony_ci     - ``'peername'``: the remote address to which the socket is
1917db96d56Sopenharmony_ci       connected, result of :meth:`socket.socket.getpeername`
1927db96d56Sopenharmony_ci       (``None`` on error)
1937db96d56Sopenharmony_ci
1947db96d56Sopenharmony_ci     - ``'socket'``: :class:`socket.socket` instance
1957db96d56Sopenharmony_ci
1967db96d56Sopenharmony_ci     - ``'sockname'``: the socket's own address,
1977db96d56Sopenharmony_ci       result of :meth:`socket.socket.getsockname`
1987db96d56Sopenharmony_ci
1997db96d56Sopenharmony_ci   * SSL socket:
2007db96d56Sopenharmony_ci
2017db96d56Sopenharmony_ci     - ``'compression'``: the compression algorithm being used as a
2027db96d56Sopenharmony_ci       string, or ``None`` if the connection isn't compressed; result
2037db96d56Sopenharmony_ci       of :meth:`ssl.SSLSocket.compression`
2047db96d56Sopenharmony_ci
2057db96d56Sopenharmony_ci     - ``'cipher'``: a three-value tuple containing the name of the
2067db96d56Sopenharmony_ci       cipher being used, the version of the SSL protocol that defines
2077db96d56Sopenharmony_ci       its use, and the number of secret bits being used; result of
2087db96d56Sopenharmony_ci       :meth:`ssl.SSLSocket.cipher`
2097db96d56Sopenharmony_ci
2107db96d56Sopenharmony_ci     - ``'peercert'``: peer certificate; result of
2117db96d56Sopenharmony_ci       :meth:`ssl.SSLSocket.getpeercert`
2127db96d56Sopenharmony_ci
2137db96d56Sopenharmony_ci     - ``'sslcontext'``: :class:`ssl.SSLContext` instance
2147db96d56Sopenharmony_ci
2157db96d56Sopenharmony_ci     - ``'ssl_object'``: :class:`ssl.SSLObject` or
2167db96d56Sopenharmony_ci       :class:`ssl.SSLSocket` instance
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ci   * pipe:
2197db96d56Sopenharmony_ci
2207db96d56Sopenharmony_ci     - ``'pipe'``: pipe object
2217db96d56Sopenharmony_ci
2227db96d56Sopenharmony_ci   * subprocess:
2237db96d56Sopenharmony_ci
2247db96d56Sopenharmony_ci     - ``'subprocess'``: :class:`subprocess.Popen` instance
2257db96d56Sopenharmony_ci
2267db96d56Sopenharmony_ci.. method:: BaseTransport.set_protocol(protocol)
2277db96d56Sopenharmony_ci
2287db96d56Sopenharmony_ci   Set a new protocol.
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci   Switching protocol should only be done when both
2317db96d56Sopenharmony_ci   protocols are documented to support the switch.
2327db96d56Sopenharmony_ci
2337db96d56Sopenharmony_ci.. method:: BaseTransport.get_protocol()
2347db96d56Sopenharmony_ci
2357db96d56Sopenharmony_ci   Return the current protocol.
2367db96d56Sopenharmony_ci
2377db96d56Sopenharmony_ci
2387db96d56Sopenharmony_ciRead-only Transports
2397db96d56Sopenharmony_ci--------------------
2407db96d56Sopenharmony_ci
2417db96d56Sopenharmony_ci.. method:: ReadTransport.is_reading()
2427db96d56Sopenharmony_ci
2437db96d56Sopenharmony_ci   Return ``True`` if the transport is receiving new data.
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ci   .. versionadded:: 3.7
2467db96d56Sopenharmony_ci
2477db96d56Sopenharmony_ci.. method:: ReadTransport.pause_reading()
2487db96d56Sopenharmony_ci
2497db96d56Sopenharmony_ci   Pause the receiving end of the transport.  No data will be passed to
2507db96d56Sopenharmony_ci   the protocol's :meth:`protocol.data_received() <Protocol.data_received>`
2517db96d56Sopenharmony_ci   method until :meth:`resume_reading` is called.
2527db96d56Sopenharmony_ci
2537db96d56Sopenharmony_ci   .. versionchanged:: 3.7
2547db96d56Sopenharmony_ci      The method is idempotent, i.e. it can be called when the
2557db96d56Sopenharmony_ci      transport is already paused or closed.
2567db96d56Sopenharmony_ci
2577db96d56Sopenharmony_ci.. method:: ReadTransport.resume_reading()
2587db96d56Sopenharmony_ci
2597db96d56Sopenharmony_ci   Resume the receiving end.  The protocol's
2607db96d56Sopenharmony_ci   :meth:`protocol.data_received() <Protocol.data_received>` method
2617db96d56Sopenharmony_ci   will be called once again if some data is available for reading.
2627db96d56Sopenharmony_ci
2637db96d56Sopenharmony_ci   .. versionchanged:: 3.7
2647db96d56Sopenharmony_ci      The method is idempotent, i.e. it can be called when the
2657db96d56Sopenharmony_ci      transport is already reading.
2667db96d56Sopenharmony_ci
2677db96d56Sopenharmony_ci
2687db96d56Sopenharmony_ciWrite-only Transports
2697db96d56Sopenharmony_ci---------------------
2707db96d56Sopenharmony_ci
2717db96d56Sopenharmony_ci.. method:: WriteTransport.abort()
2727db96d56Sopenharmony_ci
2737db96d56Sopenharmony_ci   Close the transport immediately, without waiting for pending operations
2747db96d56Sopenharmony_ci   to complete.  Buffered data will be lost.  No more data will be received.
2757db96d56Sopenharmony_ci   The protocol's :meth:`protocol.connection_lost()
2767db96d56Sopenharmony_ci   <BaseProtocol.connection_lost>` method will eventually be
2777db96d56Sopenharmony_ci   called with :const:`None` as its argument.
2787db96d56Sopenharmony_ci
2797db96d56Sopenharmony_ci.. method:: WriteTransport.can_write_eof()
2807db96d56Sopenharmony_ci
2817db96d56Sopenharmony_ci   Return :const:`True` if the transport supports
2827db96d56Sopenharmony_ci   :meth:`~WriteTransport.write_eof`, :const:`False` if not.
2837db96d56Sopenharmony_ci
2847db96d56Sopenharmony_ci.. method:: WriteTransport.get_write_buffer_size()
2857db96d56Sopenharmony_ci
2867db96d56Sopenharmony_ci   Return the current size of the output buffer used by the transport.
2877db96d56Sopenharmony_ci
2887db96d56Sopenharmony_ci.. method:: WriteTransport.get_write_buffer_limits()
2897db96d56Sopenharmony_ci
2907db96d56Sopenharmony_ci   Get the *high* and *low* watermarks for write flow control. Return a
2917db96d56Sopenharmony_ci   tuple ``(low, high)`` where *low* and *high* are positive number of
2927db96d56Sopenharmony_ci   bytes.
2937db96d56Sopenharmony_ci
2947db96d56Sopenharmony_ci   Use :meth:`set_write_buffer_limits` to set the limits.
2957db96d56Sopenharmony_ci
2967db96d56Sopenharmony_ci   .. versionadded:: 3.4.2
2977db96d56Sopenharmony_ci
2987db96d56Sopenharmony_ci.. method:: WriteTransport.set_write_buffer_limits(high=None, low=None)
2997db96d56Sopenharmony_ci
3007db96d56Sopenharmony_ci   Set the *high* and *low* watermarks for write flow control.
3017db96d56Sopenharmony_ci
3027db96d56Sopenharmony_ci   These two values (measured in number of
3037db96d56Sopenharmony_ci   bytes) control when the protocol's
3047db96d56Sopenharmony_ci   :meth:`protocol.pause_writing() <BaseProtocol.pause_writing>`
3057db96d56Sopenharmony_ci   and :meth:`protocol.resume_writing() <BaseProtocol.resume_writing>`
3067db96d56Sopenharmony_ci   methods are called. If specified, the low watermark must be less
3077db96d56Sopenharmony_ci   than or equal to the high watermark.  Neither *high* nor *low*
3087db96d56Sopenharmony_ci   can be negative.
3097db96d56Sopenharmony_ci
3107db96d56Sopenharmony_ci   :meth:`~BaseProtocol.pause_writing` is called when the buffer size
3117db96d56Sopenharmony_ci   becomes greater than or equal to the *high* value. If writing has
3127db96d56Sopenharmony_ci   been paused, :meth:`~BaseProtocol.resume_writing` is called when
3137db96d56Sopenharmony_ci   the buffer size becomes less than or equal to the *low* value.
3147db96d56Sopenharmony_ci
3157db96d56Sopenharmony_ci   The defaults are implementation-specific.  If only the
3167db96d56Sopenharmony_ci   high watermark is given, the low watermark defaults to an
3177db96d56Sopenharmony_ci   implementation-specific value less than or equal to the
3187db96d56Sopenharmony_ci   high watermark.  Setting *high* to zero forces *low* to zero as
3197db96d56Sopenharmony_ci   well, and causes :meth:`~BaseProtocol.pause_writing` to be called
3207db96d56Sopenharmony_ci   whenever the buffer becomes non-empty.  Setting *low* to zero causes
3217db96d56Sopenharmony_ci   :meth:`~BaseProtocol.resume_writing` to be called only once the
3227db96d56Sopenharmony_ci   buffer is empty. Use of zero for either limit is generally
3237db96d56Sopenharmony_ci   sub-optimal as it reduces opportunities for doing I/O and
3247db96d56Sopenharmony_ci   computation concurrently.
3257db96d56Sopenharmony_ci
3267db96d56Sopenharmony_ci   Use :meth:`~WriteTransport.get_write_buffer_limits`
3277db96d56Sopenharmony_ci   to get the limits.
3287db96d56Sopenharmony_ci
3297db96d56Sopenharmony_ci.. method:: WriteTransport.write(data)
3307db96d56Sopenharmony_ci
3317db96d56Sopenharmony_ci   Write some *data* bytes to the transport.
3327db96d56Sopenharmony_ci
3337db96d56Sopenharmony_ci   This method does not block; it buffers the data and arranges for it
3347db96d56Sopenharmony_ci   to be sent out asynchronously.
3357db96d56Sopenharmony_ci
3367db96d56Sopenharmony_ci.. method:: WriteTransport.writelines(list_of_data)
3377db96d56Sopenharmony_ci
3387db96d56Sopenharmony_ci   Write a list (or any iterable) of data bytes to the transport.
3397db96d56Sopenharmony_ci   This is functionally equivalent to calling :meth:`write` on each
3407db96d56Sopenharmony_ci   element yielded by the iterable, but may be implemented more
3417db96d56Sopenharmony_ci   efficiently.
3427db96d56Sopenharmony_ci
3437db96d56Sopenharmony_ci.. method:: WriteTransport.write_eof()
3447db96d56Sopenharmony_ci
3457db96d56Sopenharmony_ci   Close the write end of the transport after flushing all buffered data.
3467db96d56Sopenharmony_ci   Data may still be received.
3477db96d56Sopenharmony_ci
3487db96d56Sopenharmony_ci   This method can raise :exc:`NotImplementedError` if the transport
3497db96d56Sopenharmony_ci   (e.g. SSL) doesn't support half-closed connections.
3507db96d56Sopenharmony_ci
3517db96d56Sopenharmony_ci
3527db96d56Sopenharmony_ciDatagram Transports
3537db96d56Sopenharmony_ci-------------------
3547db96d56Sopenharmony_ci
3557db96d56Sopenharmony_ci.. method:: DatagramTransport.sendto(data, addr=None)
3567db96d56Sopenharmony_ci
3577db96d56Sopenharmony_ci   Send the *data* bytes to the remote peer given by *addr* (a
3587db96d56Sopenharmony_ci   transport-dependent target address).  If *addr* is :const:`None`,
3597db96d56Sopenharmony_ci   the data is sent to the target address given on transport
3607db96d56Sopenharmony_ci   creation.
3617db96d56Sopenharmony_ci
3627db96d56Sopenharmony_ci   This method does not block; it buffers the data and arranges
3637db96d56Sopenharmony_ci   for it to be sent out asynchronously.
3647db96d56Sopenharmony_ci
3657db96d56Sopenharmony_ci.. method:: DatagramTransport.abort()
3667db96d56Sopenharmony_ci
3677db96d56Sopenharmony_ci   Close the transport immediately, without waiting for pending
3687db96d56Sopenharmony_ci   operations to complete.  Buffered data will be lost.
3697db96d56Sopenharmony_ci   No more data will be received.  The protocol's
3707db96d56Sopenharmony_ci   :meth:`protocol.connection_lost() <BaseProtocol.connection_lost>`
3717db96d56Sopenharmony_ci   method will eventually be called with :const:`None` as its argument.
3727db96d56Sopenharmony_ci
3737db96d56Sopenharmony_ci
3747db96d56Sopenharmony_ci.. _asyncio-subprocess-transports:
3757db96d56Sopenharmony_ci
3767db96d56Sopenharmony_ciSubprocess Transports
3777db96d56Sopenharmony_ci---------------------
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_ci.. method:: SubprocessTransport.get_pid()
3807db96d56Sopenharmony_ci
3817db96d56Sopenharmony_ci   Return the subprocess process id as an integer.
3827db96d56Sopenharmony_ci
3837db96d56Sopenharmony_ci.. method:: SubprocessTransport.get_pipe_transport(fd)
3847db96d56Sopenharmony_ci
3857db96d56Sopenharmony_ci   Return the transport for the communication pipe corresponding to the
3867db96d56Sopenharmony_ci   integer file descriptor *fd*:
3877db96d56Sopenharmony_ci
3887db96d56Sopenharmony_ci   * ``0``: readable streaming transport of the standard input (*stdin*),
3897db96d56Sopenharmony_ci     or :const:`None` if the subprocess was not created with ``stdin=PIPE``
3907db96d56Sopenharmony_ci   * ``1``: writable streaming transport of the standard output (*stdout*),
3917db96d56Sopenharmony_ci     or :const:`None` if the subprocess was not created with ``stdout=PIPE``
3927db96d56Sopenharmony_ci   * ``2``: writable streaming transport of the standard error (*stderr*),
3937db96d56Sopenharmony_ci     or :const:`None` if the subprocess was not created with ``stderr=PIPE``
3947db96d56Sopenharmony_ci   * other *fd*: :const:`None`
3957db96d56Sopenharmony_ci
3967db96d56Sopenharmony_ci.. method:: SubprocessTransport.get_returncode()
3977db96d56Sopenharmony_ci
3987db96d56Sopenharmony_ci   Return the subprocess return code as an integer or :const:`None`
3997db96d56Sopenharmony_ci   if it hasn't returned, which is similar to the
4007db96d56Sopenharmony_ci   :attr:`subprocess.Popen.returncode` attribute.
4017db96d56Sopenharmony_ci
4027db96d56Sopenharmony_ci.. method:: SubprocessTransport.kill()
4037db96d56Sopenharmony_ci
4047db96d56Sopenharmony_ci   Kill the subprocess.
4057db96d56Sopenharmony_ci
4067db96d56Sopenharmony_ci   On POSIX systems, the function sends SIGKILL to the subprocess.
4077db96d56Sopenharmony_ci   On Windows, this method is an alias for :meth:`terminate`.
4087db96d56Sopenharmony_ci
4097db96d56Sopenharmony_ci   See also :meth:`subprocess.Popen.kill`.
4107db96d56Sopenharmony_ci
4117db96d56Sopenharmony_ci.. method:: SubprocessTransport.send_signal(signal)
4127db96d56Sopenharmony_ci
4137db96d56Sopenharmony_ci   Send the *signal* number to the subprocess, as in
4147db96d56Sopenharmony_ci   :meth:`subprocess.Popen.send_signal`.
4157db96d56Sopenharmony_ci
4167db96d56Sopenharmony_ci.. method:: SubprocessTransport.terminate()
4177db96d56Sopenharmony_ci
4187db96d56Sopenharmony_ci   Stop the subprocess.
4197db96d56Sopenharmony_ci
4207db96d56Sopenharmony_ci   On POSIX systems, this method sends SIGTERM to the subprocess.
4217db96d56Sopenharmony_ci   On Windows, the Windows API function TerminateProcess() is called to
4227db96d56Sopenharmony_ci   stop the subprocess.
4237db96d56Sopenharmony_ci
4247db96d56Sopenharmony_ci   See also :meth:`subprocess.Popen.terminate`.
4257db96d56Sopenharmony_ci
4267db96d56Sopenharmony_ci.. method:: SubprocessTransport.close()
4277db96d56Sopenharmony_ci
4287db96d56Sopenharmony_ci   Kill the subprocess by calling the :meth:`kill` method.
4297db96d56Sopenharmony_ci
4307db96d56Sopenharmony_ci   If the subprocess hasn't returned yet, and close transports of
4317db96d56Sopenharmony_ci   *stdin*, *stdout*, and *stderr* pipes.
4327db96d56Sopenharmony_ci
4337db96d56Sopenharmony_ci
4347db96d56Sopenharmony_ci.. _asyncio-protocol:
4357db96d56Sopenharmony_ci
4367db96d56Sopenharmony_ciProtocols
4377db96d56Sopenharmony_ci=========
4387db96d56Sopenharmony_ci
4397db96d56Sopenharmony_ci**Source code:** :source:`Lib/asyncio/protocols.py`
4407db96d56Sopenharmony_ci
4417db96d56Sopenharmony_ci---------------------------------------------------
4427db96d56Sopenharmony_ci
4437db96d56Sopenharmony_ciasyncio provides a set of abstract base classes that should be used
4447db96d56Sopenharmony_cito implement network protocols.  Those classes are meant to be used
4457db96d56Sopenharmony_citogether with :ref:`transports <asyncio-transport>`.
4467db96d56Sopenharmony_ci
4477db96d56Sopenharmony_ciSubclasses of abstract base protocol classes may implement some or
4487db96d56Sopenharmony_ciall methods.  All these methods are callbacks: they are called by
4497db96d56Sopenharmony_citransports on certain events, for example when some data is received.
4507db96d56Sopenharmony_ciA base protocol method should be called by the corresponding transport.
4517db96d56Sopenharmony_ci
4527db96d56Sopenharmony_ci
4537db96d56Sopenharmony_ciBase Protocols
4547db96d56Sopenharmony_ci--------------
4557db96d56Sopenharmony_ci
4567db96d56Sopenharmony_ci.. class:: BaseProtocol
4577db96d56Sopenharmony_ci
4587db96d56Sopenharmony_ci   Base protocol with methods that all protocols share.
4597db96d56Sopenharmony_ci
4607db96d56Sopenharmony_ci.. class:: Protocol(BaseProtocol)
4617db96d56Sopenharmony_ci
4627db96d56Sopenharmony_ci   The base class for implementing streaming protocols
4637db96d56Sopenharmony_ci   (TCP, Unix sockets, etc).
4647db96d56Sopenharmony_ci
4657db96d56Sopenharmony_ci.. class:: BufferedProtocol(BaseProtocol)
4667db96d56Sopenharmony_ci
4677db96d56Sopenharmony_ci   A base class for implementing streaming protocols with manual
4687db96d56Sopenharmony_ci   control of the receive buffer.
4697db96d56Sopenharmony_ci
4707db96d56Sopenharmony_ci.. class:: DatagramProtocol(BaseProtocol)
4717db96d56Sopenharmony_ci
4727db96d56Sopenharmony_ci   The base class for implementing datagram (UDP) protocols.
4737db96d56Sopenharmony_ci
4747db96d56Sopenharmony_ci.. class:: SubprocessProtocol(BaseProtocol)
4757db96d56Sopenharmony_ci
4767db96d56Sopenharmony_ci   The base class for implementing protocols communicating with child
4777db96d56Sopenharmony_ci   processes (unidirectional pipes).
4787db96d56Sopenharmony_ci
4797db96d56Sopenharmony_ci
4807db96d56Sopenharmony_ciBase Protocol
4817db96d56Sopenharmony_ci-------------
4827db96d56Sopenharmony_ci
4837db96d56Sopenharmony_ciAll asyncio protocols can implement Base Protocol callbacks.
4847db96d56Sopenharmony_ci
4857db96d56Sopenharmony_ci.. rubric:: Connection Callbacks
4867db96d56Sopenharmony_ci
4877db96d56Sopenharmony_ciConnection callbacks are called on all protocols, exactly once per
4887db96d56Sopenharmony_cia successful connection.  All other protocol callbacks can only be
4897db96d56Sopenharmony_cicalled between those two methods.
4907db96d56Sopenharmony_ci
4917db96d56Sopenharmony_ci.. method:: BaseProtocol.connection_made(transport)
4927db96d56Sopenharmony_ci
4937db96d56Sopenharmony_ci   Called when a connection is made.
4947db96d56Sopenharmony_ci
4957db96d56Sopenharmony_ci   The *transport* argument is the transport representing the
4967db96d56Sopenharmony_ci   connection.  The protocol is responsible for storing the reference
4977db96d56Sopenharmony_ci   to its transport.
4987db96d56Sopenharmony_ci
4997db96d56Sopenharmony_ci.. method:: BaseProtocol.connection_lost(exc)
5007db96d56Sopenharmony_ci
5017db96d56Sopenharmony_ci   Called when the connection is lost or closed.
5027db96d56Sopenharmony_ci
5037db96d56Sopenharmony_ci   The argument is either an exception object or :const:`None`.
5047db96d56Sopenharmony_ci   The latter means a regular EOF is received, or the connection was
5057db96d56Sopenharmony_ci   aborted or closed by this side of the connection.
5067db96d56Sopenharmony_ci
5077db96d56Sopenharmony_ci
5087db96d56Sopenharmony_ci.. rubric:: Flow Control Callbacks
5097db96d56Sopenharmony_ci
5107db96d56Sopenharmony_ciFlow control callbacks can be called by transports to pause or
5117db96d56Sopenharmony_ciresume writing performed by the protocol.
5127db96d56Sopenharmony_ci
5137db96d56Sopenharmony_ciSee the documentation of the :meth:`~WriteTransport.set_write_buffer_limits`
5147db96d56Sopenharmony_cimethod for more details.
5157db96d56Sopenharmony_ci
5167db96d56Sopenharmony_ci.. method:: BaseProtocol.pause_writing()
5177db96d56Sopenharmony_ci
5187db96d56Sopenharmony_ci   Called when the transport's buffer goes over the high watermark.
5197db96d56Sopenharmony_ci
5207db96d56Sopenharmony_ci.. method:: BaseProtocol.resume_writing()
5217db96d56Sopenharmony_ci
5227db96d56Sopenharmony_ci   Called when the transport's buffer drains below the low watermark.
5237db96d56Sopenharmony_ci
5247db96d56Sopenharmony_ciIf the buffer size equals the high watermark,
5257db96d56Sopenharmony_ci:meth:`~BaseProtocol.pause_writing` is not called: the buffer size must
5267db96d56Sopenharmony_cigo strictly over.
5277db96d56Sopenharmony_ci
5287db96d56Sopenharmony_ciConversely, :meth:`~BaseProtocol.resume_writing` is called when the
5297db96d56Sopenharmony_cibuffer size is equal or lower than the low watermark.  These end
5307db96d56Sopenharmony_ciconditions are important to ensure that things go as expected when
5317db96d56Sopenharmony_cieither mark is zero.
5327db96d56Sopenharmony_ci
5337db96d56Sopenharmony_ci
5347db96d56Sopenharmony_ciStreaming Protocols
5357db96d56Sopenharmony_ci-------------------
5367db96d56Sopenharmony_ci
5377db96d56Sopenharmony_ciEvent methods, such as :meth:`loop.create_server`,
5387db96d56Sopenharmony_ci:meth:`loop.create_unix_server`, :meth:`loop.create_connection`,
5397db96d56Sopenharmony_ci:meth:`loop.create_unix_connection`, :meth:`loop.connect_accepted_socket`,
5407db96d56Sopenharmony_ci:meth:`loop.connect_read_pipe`, and :meth:`loop.connect_write_pipe`
5417db96d56Sopenharmony_ciaccept factories that return streaming protocols.
5427db96d56Sopenharmony_ci
5437db96d56Sopenharmony_ci.. method:: Protocol.data_received(data)
5447db96d56Sopenharmony_ci
5457db96d56Sopenharmony_ci   Called when some data is received.  *data* is a non-empty bytes
5467db96d56Sopenharmony_ci   object containing the incoming data.
5477db96d56Sopenharmony_ci
5487db96d56Sopenharmony_ci   Whether the data is buffered, chunked or reassembled depends on
5497db96d56Sopenharmony_ci   the transport.  In general, you shouldn't rely on specific semantics
5507db96d56Sopenharmony_ci   and instead make your parsing generic and flexible. However,
5517db96d56Sopenharmony_ci   data is always received in the correct order.
5527db96d56Sopenharmony_ci
5537db96d56Sopenharmony_ci   The method can be called an arbitrary number of times while
5547db96d56Sopenharmony_ci   a connection is open.
5557db96d56Sopenharmony_ci
5567db96d56Sopenharmony_ci   However, :meth:`protocol.eof_received() <Protocol.eof_received>`
5577db96d56Sopenharmony_ci   is called at most once.  Once ``eof_received()`` is called,
5587db96d56Sopenharmony_ci   ``data_received()`` is not called anymore.
5597db96d56Sopenharmony_ci
5607db96d56Sopenharmony_ci.. method:: Protocol.eof_received()
5617db96d56Sopenharmony_ci
5627db96d56Sopenharmony_ci   Called when the other end signals it won't send any more data
5637db96d56Sopenharmony_ci   (for example by calling :meth:`transport.write_eof()
5647db96d56Sopenharmony_ci   <WriteTransport.write_eof>`, if the other end also uses
5657db96d56Sopenharmony_ci   asyncio).
5667db96d56Sopenharmony_ci
5677db96d56Sopenharmony_ci   This method may return a false value (including ``None``), in which case
5687db96d56Sopenharmony_ci   the transport will close itself.  Conversely, if this method returns a
5697db96d56Sopenharmony_ci   true value, the protocol used determines whether to close the transport.
5707db96d56Sopenharmony_ci   Since the default implementation returns ``None``, it implicitly closes the
5717db96d56Sopenharmony_ci   connection.
5727db96d56Sopenharmony_ci
5737db96d56Sopenharmony_ci   Some transports, including SSL, don't support half-closed connections,
5747db96d56Sopenharmony_ci   in which case returning true from this method will result in the connection
5757db96d56Sopenharmony_ci   being closed.
5767db96d56Sopenharmony_ci
5777db96d56Sopenharmony_ci
5787db96d56Sopenharmony_ciState machine:
5797db96d56Sopenharmony_ci
5807db96d56Sopenharmony_ci.. code-block:: none
5817db96d56Sopenharmony_ci
5827db96d56Sopenharmony_ci    start -> connection_made
5837db96d56Sopenharmony_ci        [-> data_received]*
5847db96d56Sopenharmony_ci        [-> eof_received]?
5857db96d56Sopenharmony_ci    -> connection_lost -> end
5867db96d56Sopenharmony_ci
5877db96d56Sopenharmony_ci
5887db96d56Sopenharmony_ciBuffered Streaming Protocols
5897db96d56Sopenharmony_ci----------------------------
5907db96d56Sopenharmony_ci
5917db96d56Sopenharmony_ci.. versionadded:: 3.7
5927db96d56Sopenharmony_ci
5937db96d56Sopenharmony_ciBuffered Protocols can be used with any event loop method
5947db96d56Sopenharmony_cithat supports `Streaming Protocols`_.
5957db96d56Sopenharmony_ci
5967db96d56Sopenharmony_ci``BufferedProtocol`` implementations allow explicit manual allocation
5977db96d56Sopenharmony_ciand control of the receive buffer.  Event loops can then use the buffer
5987db96d56Sopenharmony_ciprovided by the protocol to avoid unnecessary data copies.  This
5997db96d56Sopenharmony_cican result in noticeable performance improvement for protocols that
6007db96d56Sopenharmony_cireceive big amounts of data.  Sophisticated protocol implementations
6017db96d56Sopenharmony_cican significantly reduce the number of buffer allocations.
6027db96d56Sopenharmony_ci
6037db96d56Sopenharmony_ciThe following callbacks are called on :class:`BufferedProtocol`
6047db96d56Sopenharmony_ciinstances:
6057db96d56Sopenharmony_ci
6067db96d56Sopenharmony_ci.. method:: BufferedProtocol.get_buffer(sizehint)
6077db96d56Sopenharmony_ci
6087db96d56Sopenharmony_ci   Called to allocate a new receive buffer.
6097db96d56Sopenharmony_ci
6107db96d56Sopenharmony_ci   *sizehint* is the recommended minimum size for the returned
6117db96d56Sopenharmony_ci   buffer.  It is acceptable to return smaller or larger buffers
6127db96d56Sopenharmony_ci   than what *sizehint* suggests.  When set to -1, the buffer size
6137db96d56Sopenharmony_ci   can be arbitrary. It is an error to return a buffer with a zero size.
6147db96d56Sopenharmony_ci
6157db96d56Sopenharmony_ci   ``get_buffer()`` must return an object implementing the
6167db96d56Sopenharmony_ci   :ref:`buffer protocol <bufferobjects>`.
6177db96d56Sopenharmony_ci
6187db96d56Sopenharmony_ci.. method:: BufferedProtocol.buffer_updated(nbytes)
6197db96d56Sopenharmony_ci
6207db96d56Sopenharmony_ci   Called when the buffer was updated with the received data.
6217db96d56Sopenharmony_ci
6227db96d56Sopenharmony_ci   *nbytes* is the total number of bytes that were written to the buffer.
6237db96d56Sopenharmony_ci
6247db96d56Sopenharmony_ci.. method:: BufferedProtocol.eof_received()
6257db96d56Sopenharmony_ci
6267db96d56Sopenharmony_ci   See the documentation of the :meth:`protocol.eof_received()
6277db96d56Sopenharmony_ci   <Protocol.eof_received>` method.
6287db96d56Sopenharmony_ci
6297db96d56Sopenharmony_ci
6307db96d56Sopenharmony_ci:meth:`~BufferedProtocol.get_buffer` can be called an arbitrary number
6317db96d56Sopenharmony_ciof times during a connection.  However, :meth:`protocol.eof_received()
6327db96d56Sopenharmony_ci<Protocol.eof_received>` is called at most once
6337db96d56Sopenharmony_ciand, if called, :meth:`~BufferedProtocol.get_buffer` and
6347db96d56Sopenharmony_ci:meth:`~BufferedProtocol.buffer_updated` won't be called after it.
6357db96d56Sopenharmony_ci
6367db96d56Sopenharmony_ciState machine:
6377db96d56Sopenharmony_ci
6387db96d56Sopenharmony_ci.. code-block:: none
6397db96d56Sopenharmony_ci
6407db96d56Sopenharmony_ci    start -> connection_made
6417db96d56Sopenharmony_ci        [-> get_buffer
6427db96d56Sopenharmony_ci            [-> buffer_updated]?
6437db96d56Sopenharmony_ci        ]*
6447db96d56Sopenharmony_ci        [-> eof_received]?
6457db96d56Sopenharmony_ci    -> connection_lost -> end
6467db96d56Sopenharmony_ci
6477db96d56Sopenharmony_ci
6487db96d56Sopenharmony_ciDatagram Protocols
6497db96d56Sopenharmony_ci------------------
6507db96d56Sopenharmony_ci
6517db96d56Sopenharmony_ciDatagram Protocol instances should be constructed by protocol
6527db96d56Sopenharmony_cifactories passed to the :meth:`loop.create_datagram_endpoint` method.
6537db96d56Sopenharmony_ci
6547db96d56Sopenharmony_ci.. method:: DatagramProtocol.datagram_received(data, addr)
6557db96d56Sopenharmony_ci
6567db96d56Sopenharmony_ci   Called when a datagram is received.  *data* is a bytes object containing
6577db96d56Sopenharmony_ci   the incoming data.  *addr* is the address of the peer sending the data;
6587db96d56Sopenharmony_ci   the exact format depends on the transport.
6597db96d56Sopenharmony_ci
6607db96d56Sopenharmony_ci.. method:: DatagramProtocol.error_received(exc)
6617db96d56Sopenharmony_ci
6627db96d56Sopenharmony_ci   Called when a previous send or receive operation raises an
6637db96d56Sopenharmony_ci   :class:`OSError`.  *exc* is the :class:`OSError` instance.
6647db96d56Sopenharmony_ci
6657db96d56Sopenharmony_ci   This method is called in rare conditions, when the transport (e.g. UDP)
6667db96d56Sopenharmony_ci   detects that a datagram could not be delivered to its recipient.
6677db96d56Sopenharmony_ci   In many conditions though, undeliverable datagrams will be silently
6687db96d56Sopenharmony_ci   dropped.
6697db96d56Sopenharmony_ci
6707db96d56Sopenharmony_ci.. note::
6717db96d56Sopenharmony_ci
6727db96d56Sopenharmony_ci   On BSD systems (macOS, FreeBSD, etc.) flow control is not supported
6737db96d56Sopenharmony_ci   for datagram protocols, because there is no reliable way to detect send
6747db96d56Sopenharmony_ci   failures caused by writing too many packets.
6757db96d56Sopenharmony_ci
6767db96d56Sopenharmony_ci   The socket always appears 'ready' and excess packets are dropped. An
6777db96d56Sopenharmony_ci   :class:`OSError` with ``errno`` set to :const:`errno.ENOBUFS` may
6787db96d56Sopenharmony_ci   or may not be raised; if it is raised, it will be reported to
6797db96d56Sopenharmony_ci   :meth:`DatagramProtocol.error_received` but otherwise ignored.
6807db96d56Sopenharmony_ci
6817db96d56Sopenharmony_ci
6827db96d56Sopenharmony_ci.. _asyncio-subprocess-protocols:
6837db96d56Sopenharmony_ci
6847db96d56Sopenharmony_ciSubprocess Protocols
6857db96d56Sopenharmony_ci--------------------
6867db96d56Sopenharmony_ci
6877db96d56Sopenharmony_ciSubprocess Protocol instances should be constructed by protocol
6887db96d56Sopenharmony_cifactories passed to the :meth:`loop.subprocess_exec` and
6897db96d56Sopenharmony_ci:meth:`loop.subprocess_shell` methods.
6907db96d56Sopenharmony_ci
6917db96d56Sopenharmony_ci.. method:: SubprocessProtocol.pipe_data_received(fd, data)
6927db96d56Sopenharmony_ci
6937db96d56Sopenharmony_ci   Called when the child process writes data into its stdout or stderr
6947db96d56Sopenharmony_ci   pipe.
6957db96d56Sopenharmony_ci
6967db96d56Sopenharmony_ci   *fd* is the integer file descriptor of the pipe.
6977db96d56Sopenharmony_ci
6987db96d56Sopenharmony_ci   *data* is a non-empty bytes object containing the received data.
6997db96d56Sopenharmony_ci
7007db96d56Sopenharmony_ci.. method:: SubprocessProtocol.pipe_connection_lost(fd, exc)
7017db96d56Sopenharmony_ci
7027db96d56Sopenharmony_ci   Called when one of the pipes communicating with the child process
7037db96d56Sopenharmony_ci   is closed.
7047db96d56Sopenharmony_ci
7057db96d56Sopenharmony_ci   *fd* is the integer file descriptor that was closed.
7067db96d56Sopenharmony_ci
7077db96d56Sopenharmony_ci.. method:: SubprocessProtocol.process_exited()
7087db96d56Sopenharmony_ci
7097db96d56Sopenharmony_ci   Called when the child process has exited.
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_ci
7127db96d56Sopenharmony_ciExamples
7137db96d56Sopenharmony_ci========
7147db96d56Sopenharmony_ci
7157db96d56Sopenharmony_ci.. _asyncio_example_tcp_echo_server_protocol:
7167db96d56Sopenharmony_ci
7177db96d56Sopenharmony_ciTCP Echo Server
7187db96d56Sopenharmony_ci---------------
7197db96d56Sopenharmony_ci
7207db96d56Sopenharmony_ciCreate a TCP echo server using the :meth:`loop.create_server` method, send back
7217db96d56Sopenharmony_cireceived data, and close the connection::
7227db96d56Sopenharmony_ci
7237db96d56Sopenharmony_ci    import asyncio
7247db96d56Sopenharmony_ci
7257db96d56Sopenharmony_ci
7267db96d56Sopenharmony_ci    class EchoServerProtocol(asyncio.Protocol):
7277db96d56Sopenharmony_ci        def connection_made(self, transport):
7287db96d56Sopenharmony_ci            peername = transport.get_extra_info('peername')
7297db96d56Sopenharmony_ci            print('Connection from {}'.format(peername))
7307db96d56Sopenharmony_ci            self.transport = transport
7317db96d56Sopenharmony_ci
7327db96d56Sopenharmony_ci        def data_received(self, data):
7337db96d56Sopenharmony_ci            message = data.decode()
7347db96d56Sopenharmony_ci            print('Data received: {!r}'.format(message))
7357db96d56Sopenharmony_ci
7367db96d56Sopenharmony_ci            print('Send: {!r}'.format(message))
7377db96d56Sopenharmony_ci            self.transport.write(data)
7387db96d56Sopenharmony_ci
7397db96d56Sopenharmony_ci            print('Close the client socket')
7407db96d56Sopenharmony_ci            self.transport.close()
7417db96d56Sopenharmony_ci
7427db96d56Sopenharmony_ci
7437db96d56Sopenharmony_ci    async def main():
7447db96d56Sopenharmony_ci        # Get a reference to the event loop as we plan to use
7457db96d56Sopenharmony_ci        # low-level APIs.
7467db96d56Sopenharmony_ci        loop = asyncio.get_running_loop()
7477db96d56Sopenharmony_ci
7487db96d56Sopenharmony_ci        server = await loop.create_server(
7497db96d56Sopenharmony_ci            lambda: EchoServerProtocol(),
7507db96d56Sopenharmony_ci            '127.0.0.1', 8888)
7517db96d56Sopenharmony_ci
7527db96d56Sopenharmony_ci        async with server:
7537db96d56Sopenharmony_ci            await server.serve_forever()
7547db96d56Sopenharmony_ci
7557db96d56Sopenharmony_ci
7567db96d56Sopenharmony_ci    asyncio.run(main())
7577db96d56Sopenharmony_ci
7587db96d56Sopenharmony_ci
7597db96d56Sopenharmony_ci.. seealso::
7607db96d56Sopenharmony_ci
7617db96d56Sopenharmony_ci   The :ref:`TCP echo server using streams <asyncio-tcp-echo-server-streams>`
7627db96d56Sopenharmony_ci   example uses the high-level :func:`asyncio.start_server` function.
7637db96d56Sopenharmony_ci
7647db96d56Sopenharmony_ci.. _asyncio_example_tcp_echo_client_protocol:
7657db96d56Sopenharmony_ci
7667db96d56Sopenharmony_ciTCP Echo Client
7677db96d56Sopenharmony_ci---------------
7687db96d56Sopenharmony_ci
7697db96d56Sopenharmony_ciA TCP echo client using the :meth:`loop.create_connection` method, sends
7707db96d56Sopenharmony_cidata, and waits until the connection is closed::
7717db96d56Sopenharmony_ci
7727db96d56Sopenharmony_ci    import asyncio
7737db96d56Sopenharmony_ci
7747db96d56Sopenharmony_ci
7757db96d56Sopenharmony_ci    class EchoClientProtocol(asyncio.Protocol):
7767db96d56Sopenharmony_ci        def __init__(self, message, on_con_lost):
7777db96d56Sopenharmony_ci            self.message = message
7787db96d56Sopenharmony_ci            self.on_con_lost = on_con_lost
7797db96d56Sopenharmony_ci
7807db96d56Sopenharmony_ci        def connection_made(self, transport):
7817db96d56Sopenharmony_ci            transport.write(self.message.encode())
7827db96d56Sopenharmony_ci            print('Data sent: {!r}'.format(self.message))
7837db96d56Sopenharmony_ci
7847db96d56Sopenharmony_ci        def data_received(self, data):
7857db96d56Sopenharmony_ci            print('Data received: {!r}'.format(data.decode()))
7867db96d56Sopenharmony_ci
7877db96d56Sopenharmony_ci        def connection_lost(self, exc):
7887db96d56Sopenharmony_ci            print('The server closed the connection')
7897db96d56Sopenharmony_ci            self.on_con_lost.set_result(True)
7907db96d56Sopenharmony_ci
7917db96d56Sopenharmony_ci
7927db96d56Sopenharmony_ci    async def main():
7937db96d56Sopenharmony_ci        # Get a reference to the event loop as we plan to use
7947db96d56Sopenharmony_ci        # low-level APIs.
7957db96d56Sopenharmony_ci        loop = asyncio.get_running_loop()
7967db96d56Sopenharmony_ci
7977db96d56Sopenharmony_ci        on_con_lost = loop.create_future()
7987db96d56Sopenharmony_ci        message = 'Hello World!'
7997db96d56Sopenharmony_ci
8007db96d56Sopenharmony_ci        transport, protocol = await loop.create_connection(
8017db96d56Sopenharmony_ci            lambda: EchoClientProtocol(message, on_con_lost),
8027db96d56Sopenharmony_ci            '127.0.0.1', 8888)
8037db96d56Sopenharmony_ci
8047db96d56Sopenharmony_ci        # Wait until the protocol signals that the connection
8057db96d56Sopenharmony_ci        # is lost and close the transport.
8067db96d56Sopenharmony_ci        try:
8077db96d56Sopenharmony_ci            await on_con_lost
8087db96d56Sopenharmony_ci        finally:
8097db96d56Sopenharmony_ci            transport.close()
8107db96d56Sopenharmony_ci
8117db96d56Sopenharmony_ci
8127db96d56Sopenharmony_ci    asyncio.run(main())
8137db96d56Sopenharmony_ci
8147db96d56Sopenharmony_ci
8157db96d56Sopenharmony_ci.. seealso::
8167db96d56Sopenharmony_ci
8177db96d56Sopenharmony_ci   The :ref:`TCP echo client using streams <asyncio-tcp-echo-client-streams>`
8187db96d56Sopenharmony_ci   example uses the high-level :func:`asyncio.open_connection` function.
8197db96d56Sopenharmony_ci
8207db96d56Sopenharmony_ci
8217db96d56Sopenharmony_ci.. _asyncio-udp-echo-server-protocol:
8227db96d56Sopenharmony_ci
8237db96d56Sopenharmony_ciUDP Echo Server
8247db96d56Sopenharmony_ci---------------
8257db96d56Sopenharmony_ci
8267db96d56Sopenharmony_ciA UDP echo server, using the :meth:`loop.create_datagram_endpoint`
8277db96d56Sopenharmony_cimethod, sends back received data::
8287db96d56Sopenharmony_ci
8297db96d56Sopenharmony_ci    import asyncio
8307db96d56Sopenharmony_ci
8317db96d56Sopenharmony_ci
8327db96d56Sopenharmony_ci    class EchoServerProtocol:
8337db96d56Sopenharmony_ci        def connection_made(self, transport):
8347db96d56Sopenharmony_ci            self.transport = transport
8357db96d56Sopenharmony_ci
8367db96d56Sopenharmony_ci        def datagram_received(self, data, addr):
8377db96d56Sopenharmony_ci            message = data.decode()
8387db96d56Sopenharmony_ci            print('Received %r from %s' % (message, addr))
8397db96d56Sopenharmony_ci            print('Send %r to %s' % (message, addr))
8407db96d56Sopenharmony_ci            self.transport.sendto(data, addr)
8417db96d56Sopenharmony_ci
8427db96d56Sopenharmony_ci
8437db96d56Sopenharmony_ci    async def main():
8447db96d56Sopenharmony_ci        print("Starting UDP server")
8457db96d56Sopenharmony_ci
8467db96d56Sopenharmony_ci        # Get a reference to the event loop as we plan to use
8477db96d56Sopenharmony_ci        # low-level APIs.
8487db96d56Sopenharmony_ci        loop = asyncio.get_running_loop()
8497db96d56Sopenharmony_ci
8507db96d56Sopenharmony_ci        # One protocol instance will be created to serve all
8517db96d56Sopenharmony_ci        # client requests.
8527db96d56Sopenharmony_ci        transport, protocol = await loop.create_datagram_endpoint(
8537db96d56Sopenharmony_ci            lambda: EchoServerProtocol(),
8547db96d56Sopenharmony_ci            local_addr=('127.0.0.1', 9999))
8557db96d56Sopenharmony_ci
8567db96d56Sopenharmony_ci        try:
8577db96d56Sopenharmony_ci            await asyncio.sleep(3600)  # Serve for 1 hour.
8587db96d56Sopenharmony_ci        finally:
8597db96d56Sopenharmony_ci            transport.close()
8607db96d56Sopenharmony_ci
8617db96d56Sopenharmony_ci
8627db96d56Sopenharmony_ci    asyncio.run(main())
8637db96d56Sopenharmony_ci
8647db96d56Sopenharmony_ci
8657db96d56Sopenharmony_ci.. _asyncio-udp-echo-client-protocol:
8667db96d56Sopenharmony_ci
8677db96d56Sopenharmony_ciUDP Echo Client
8687db96d56Sopenharmony_ci---------------
8697db96d56Sopenharmony_ci
8707db96d56Sopenharmony_ciA UDP echo client, using the :meth:`loop.create_datagram_endpoint`
8717db96d56Sopenharmony_cimethod, sends data and closes the transport when it receives the answer::
8727db96d56Sopenharmony_ci
8737db96d56Sopenharmony_ci    import asyncio
8747db96d56Sopenharmony_ci
8757db96d56Sopenharmony_ci
8767db96d56Sopenharmony_ci    class EchoClientProtocol:
8777db96d56Sopenharmony_ci        def __init__(self, message, on_con_lost):
8787db96d56Sopenharmony_ci            self.message = message
8797db96d56Sopenharmony_ci            self.on_con_lost = on_con_lost
8807db96d56Sopenharmony_ci            self.transport = None
8817db96d56Sopenharmony_ci
8827db96d56Sopenharmony_ci        def connection_made(self, transport):
8837db96d56Sopenharmony_ci            self.transport = transport
8847db96d56Sopenharmony_ci            print('Send:', self.message)
8857db96d56Sopenharmony_ci            self.transport.sendto(self.message.encode())
8867db96d56Sopenharmony_ci
8877db96d56Sopenharmony_ci        def datagram_received(self, data, addr):
8887db96d56Sopenharmony_ci            print("Received:", data.decode())
8897db96d56Sopenharmony_ci
8907db96d56Sopenharmony_ci            print("Close the socket")
8917db96d56Sopenharmony_ci            self.transport.close()
8927db96d56Sopenharmony_ci
8937db96d56Sopenharmony_ci        def error_received(self, exc):
8947db96d56Sopenharmony_ci            print('Error received:', exc)
8957db96d56Sopenharmony_ci
8967db96d56Sopenharmony_ci        def connection_lost(self, exc):
8977db96d56Sopenharmony_ci            print("Connection closed")
8987db96d56Sopenharmony_ci            self.on_con_lost.set_result(True)
8997db96d56Sopenharmony_ci
9007db96d56Sopenharmony_ci
9017db96d56Sopenharmony_ci    async def main():
9027db96d56Sopenharmony_ci        # Get a reference to the event loop as we plan to use
9037db96d56Sopenharmony_ci        # low-level APIs.
9047db96d56Sopenharmony_ci        loop = asyncio.get_running_loop()
9057db96d56Sopenharmony_ci
9067db96d56Sopenharmony_ci        on_con_lost = loop.create_future()
9077db96d56Sopenharmony_ci        message = "Hello World!"
9087db96d56Sopenharmony_ci
9097db96d56Sopenharmony_ci        transport, protocol = await loop.create_datagram_endpoint(
9107db96d56Sopenharmony_ci            lambda: EchoClientProtocol(message, on_con_lost),
9117db96d56Sopenharmony_ci            remote_addr=('127.0.0.1', 9999))
9127db96d56Sopenharmony_ci
9137db96d56Sopenharmony_ci        try:
9147db96d56Sopenharmony_ci            await on_con_lost
9157db96d56Sopenharmony_ci        finally:
9167db96d56Sopenharmony_ci            transport.close()
9177db96d56Sopenharmony_ci
9187db96d56Sopenharmony_ci
9197db96d56Sopenharmony_ci    asyncio.run(main())
9207db96d56Sopenharmony_ci
9217db96d56Sopenharmony_ci
9227db96d56Sopenharmony_ci.. _asyncio_example_create_connection:
9237db96d56Sopenharmony_ci
9247db96d56Sopenharmony_ciConnecting Existing Sockets
9257db96d56Sopenharmony_ci---------------------------
9267db96d56Sopenharmony_ci
9277db96d56Sopenharmony_ciWait until a socket receives data using the
9287db96d56Sopenharmony_ci:meth:`loop.create_connection` method with a protocol::
9297db96d56Sopenharmony_ci
9307db96d56Sopenharmony_ci    import asyncio
9317db96d56Sopenharmony_ci    import socket
9327db96d56Sopenharmony_ci
9337db96d56Sopenharmony_ci
9347db96d56Sopenharmony_ci    class MyProtocol(asyncio.Protocol):
9357db96d56Sopenharmony_ci
9367db96d56Sopenharmony_ci        def __init__(self, on_con_lost):
9377db96d56Sopenharmony_ci            self.transport = None
9387db96d56Sopenharmony_ci            self.on_con_lost = on_con_lost
9397db96d56Sopenharmony_ci
9407db96d56Sopenharmony_ci        def connection_made(self, transport):
9417db96d56Sopenharmony_ci            self.transport = transport
9427db96d56Sopenharmony_ci
9437db96d56Sopenharmony_ci        def data_received(self, data):
9447db96d56Sopenharmony_ci            print("Received:", data.decode())
9457db96d56Sopenharmony_ci
9467db96d56Sopenharmony_ci            # We are done: close the transport;
9477db96d56Sopenharmony_ci            # connection_lost() will be called automatically.
9487db96d56Sopenharmony_ci            self.transport.close()
9497db96d56Sopenharmony_ci
9507db96d56Sopenharmony_ci        def connection_lost(self, exc):
9517db96d56Sopenharmony_ci            # The socket has been closed
9527db96d56Sopenharmony_ci            self.on_con_lost.set_result(True)
9537db96d56Sopenharmony_ci
9547db96d56Sopenharmony_ci
9557db96d56Sopenharmony_ci    async def main():
9567db96d56Sopenharmony_ci        # Get a reference to the event loop as we plan to use
9577db96d56Sopenharmony_ci        # low-level APIs.
9587db96d56Sopenharmony_ci        loop = asyncio.get_running_loop()
9597db96d56Sopenharmony_ci        on_con_lost = loop.create_future()
9607db96d56Sopenharmony_ci
9617db96d56Sopenharmony_ci        # Create a pair of connected sockets
9627db96d56Sopenharmony_ci        rsock, wsock = socket.socketpair()
9637db96d56Sopenharmony_ci
9647db96d56Sopenharmony_ci        # Register the socket to wait for data.
9657db96d56Sopenharmony_ci        transport, protocol = await loop.create_connection(
9667db96d56Sopenharmony_ci            lambda: MyProtocol(on_con_lost), sock=rsock)
9677db96d56Sopenharmony_ci
9687db96d56Sopenharmony_ci        # Simulate the reception of data from the network.
9697db96d56Sopenharmony_ci        loop.call_soon(wsock.send, 'abc'.encode())
9707db96d56Sopenharmony_ci
9717db96d56Sopenharmony_ci        try:
9727db96d56Sopenharmony_ci            await protocol.on_con_lost
9737db96d56Sopenharmony_ci        finally:
9747db96d56Sopenharmony_ci            transport.close()
9757db96d56Sopenharmony_ci            wsock.close()
9767db96d56Sopenharmony_ci
9777db96d56Sopenharmony_ci    asyncio.run(main())
9787db96d56Sopenharmony_ci
9797db96d56Sopenharmony_ci.. seealso::
9807db96d56Sopenharmony_ci
9817db96d56Sopenharmony_ci   The :ref:`watch a file descriptor for read events
9827db96d56Sopenharmony_ci   <asyncio_example_watch_fd>` example uses the low-level
9837db96d56Sopenharmony_ci   :meth:`loop.add_reader` method to register an FD.
9847db96d56Sopenharmony_ci
9857db96d56Sopenharmony_ci   The :ref:`register an open socket to wait for data using streams
9867db96d56Sopenharmony_ci   <asyncio_example_create_connection-streams>` example uses high-level streams
9877db96d56Sopenharmony_ci   created by the :func:`open_connection` function in a coroutine.
9887db96d56Sopenharmony_ci
9897db96d56Sopenharmony_ci.. _asyncio_example_subprocess_proto:
9907db96d56Sopenharmony_ci
9917db96d56Sopenharmony_ciloop.subprocess_exec() and SubprocessProtocol
9927db96d56Sopenharmony_ci---------------------------------------------
9937db96d56Sopenharmony_ci
9947db96d56Sopenharmony_ciAn example of a subprocess protocol used to get the output of a
9957db96d56Sopenharmony_cisubprocess and to wait for the subprocess exit.
9967db96d56Sopenharmony_ci
9977db96d56Sopenharmony_ciThe subprocess is created by the :meth:`loop.subprocess_exec` method::
9987db96d56Sopenharmony_ci
9997db96d56Sopenharmony_ci    import asyncio
10007db96d56Sopenharmony_ci    import sys
10017db96d56Sopenharmony_ci
10027db96d56Sopenharmony_ci    class DateProtocol(asyncio.SubprocessProtocol):
10037db96d56Sopenharmony_ci        def __init__(self, exit_future):
10047db96d56Sopenharmony_ci            self.exit_future = exit_future
10057db96d56Sopenharmony_ci            self.output = bytearray()
10067db96d56Sopenharmony_ci
10077db96d56Sopenharmony_ci        def pipe_data_received(self, fd, data):
10087db96d56Sopenharmony_ci            self.output.extend(data)
10097db96d56Sopenharmony_ci
10107db96d56Sopenharmony_ci        def process_exited(self):
10117db96d56Sopenharmony_ci            self.exit_future.set_result(True)
10127db96d56Sopenharmony_ci
10137db96d56Sopenharmony_ci    async def get_date():
10147db96d56Sopenharmony_ci        # Get a reference to the event loop as we plan to use
10157db96d56Sopenharmony_ci        # low-level APIs.
10167db96d56Sopenharmony_ci        loop = asyncio.get_running_loop()
10177db96d56Sopenharmony_ci
10187db96d56Sopenharmony_ci        code = 'import datetime; print(datetime.datetime.now())'
10197db96d56Sopenharmony_ci        exit_future = asyncio.Future(loop=loop)
10207db96d56Sopenharmony_ci
10217db96d56Sopenharmony_ci        # Create the subprocess controlled by DateProtocol;
10227db96d56Sopenharmony_ci        # redirect the standard output into a pipe.
10237db96d56Sopenharmony_ci        transport, protocol = await loop.subprocess_exec(
10247db96d56Sopenharmony_ci            lambda: DateProtocol(exit_future),
10257db96d56Sopenharmony_ci            sys.executable, '-c', code,
10267db96d56Sopenharmony_ci            stdin=None, stderr=None)
10277db96d56Sopenharmony_ci
10287db96d56Sopenharmony_ci        # Wait for the subprocess exit using the process_exited()
10297db96d56Sopenharmony_ci        # method of the protocol.
10307db96d56Sopenharmony_ci        await exit_future
10317db96d56Sopenharmony_ci
10327db96d56Sopenharmony_ci        # Close the stdout pipe.
10337db96d56Sopenharmony_ci        transport.close()
10347db96d56Sopenharmony_ci
10357db96d56Sopenharmony_ci        # Read the output which was collected by the
10367db96d56Sopenharmony_ci        # pipe_data_received() method of the protocol.
10377db96d56Sopenharmony_ci        data = bytes(protocol.output)
10387db96d56Sopenharmony_ci        return data.decode('ascii').rstrip()
10397db96d56Sopenharmony_ci
10407db96d56Sopenharmony_ci    date = asyncio.run(get_date())
10417db96d56Sopenharmony_ci    print(f"Current date: {date}")
10427db96d56Sopenharmony_ci
10437db96d56Sopenharmony_ciSee also the :ref:`same example <asyncio_example_create_subprocess_exec>`
10447db96d56Sopenharmony_ciwritten using high-level APIs.
1045