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