| 
									
										
										
										
											2013-12-20 14:37:39 -05:00
										 |  |  | .. currentmodule:: asyncio
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-16 21:30:52 -05:00
										 |  |  | ++++++++++++++++++++++++++++++++++++++++++++++
 | 
					
						
							|  |  |  | Transports  and protocols (callback based API)
 | 
					
						
							|  |  |  | ++++++++++++++++++++++++++++++++++++++++++++++
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:49:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-02 15:03:02 +01:00
										 |  |  | .. _asyncio-transport:
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | Transports
 | 
					
						
							|  |  |  | ==========
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-29 21:14:04 -07:00
										 |  |  | Transports are classes provided by :mod:`asyncio` in order to abstract
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | various kinds of communication channels.  You generally won't instantiate
 | 
					
						
							| 
									
										
										
										
											2016-08-20 08:03:06 +00:00
										 |  |  | a transport yourself; instead, you will call an :class:`AbstractEventLoop` method
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | which will create the transport and try to initiate the underlying
 | 
					
						
							|  |  |  | communication channel, calling you back when it succeeds.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Once the communication channel is established, a transport is always
 | 
					
						
							| 
									
										
										
										
											2014-02-02 15:03:02 +01:00
										 |  |  | paired with a :ref:`protocol <asyncio-protocol>` instance.  The protocol can
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | then call the transport's methods for various purposes.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :mod:`asyncio` currently implements transports for TCP, UDP, SSL, and
 | 
					
						
							|  |  |  | subprocess pipes.  The methods available on a transport depend on
 | 
					
						
							|  |  |  | the transport's kind.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-25 14:24:15 +01:00
										 |  |  | The transport classes are :ref:`not thread safe <asyncio-multithreading>`.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  | BaseTransport
 | 
					
						
							|  |  |  | -------------
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. class:: BaseTransport
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Base class for transports.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. method:: close(self)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Close the transport.  If the transport has a buffer for outgoing
 | 
					
						
							|  |  |  |       data, buffered data will be flushed asynchronously.  No more data
 | 
					
						
							|  |  |  |       will be received.  After all buffered data is flushed, the
 | 
					
						
							|  |  |  |       protocol's :meth:`connection_lost` method will be called with
 | 
					
						
							|  |  |  |       :const:`None` as its argument.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-16 12:46:41 -05:00
										 |  |  |    .. method:: is_closing(self)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Return ``True`` if the transport is closing or is closed.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-16 12:47:15 -05:00
										 |  |  |       .. versionadded:: 3.5.1
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |    .. method:: get_extra_info(name, default=None)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Return optional transport information.  *name* is a string representing
 | 
					
						
							|  |  |  |       the piece of transport-specific information to get, *default* is the
 | 
					
						
							|  |  |  |       value to return if the information doesn't exist.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       This method allows transport implementations to easily expose
 | 
					
						
							|  |  |  |       channel-specific information.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       * socket:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         - ``'peername'``: the remote address to which the socket is connected,
 | 
					
						
							|  |  |  |           result of :meth:`socket.socket.getpeername` (``None`` on error)
 | 
					
						
							|  |  |  |         - ``'socket'``: :class:`socket.socket` instance
 | 
					
						
							|  |  |  |         - ``'sockname'``: the socket's own address,
 | 
					
						
							|  |  |  |           result of :meth:`socket.socket.getsockname`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       * SSL socket:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         - ``'compression'``: the compression algorithm being used as a string,
 | 
					
						
							|  |  |  |           or ``None`` if the connection isn't compressed; result of
 | 
					
						
							|  |  |  |           :meth:`ssl.SSLSocket.compression`
 | 
					
						
							|  |  |  |         - ``'cipher'``: a three-value tuple containing the name of the cipher
 | 
					
						
							|  |  |  |           being used, the version of the SSL protocol that defines its use, and
 | 
					
						
							|  |  |  |           the number of secret bits being used; result of
 | 
					
						
							|  |  |  |           :meth:`ssl.SSLSocket.cipher`
 | 
					
						
							|  |  |  |         - ``'peercert'``: peer certificate; result of
 | 
					
						
							|  |  |  |           :meth:`ssl.SSLSocket.getpeercert`
 | 
					
						
							|  |  |  |         - ``'sslcontext'``: :class:`ssl.SSLContext` instance
 | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |         - ``'ssl_object'``: :class:`ssl.SSLObject` or :class:`ssl.SSLSocket`
 | 
					
						
							|  |  |  |           instance
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       * pipe:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         - ``'pipe'``: pipe object
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       * subprocess:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         - ``'subprocess'``: :class:`subprocess.Popen` instance
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 18:27:52 +02:00
										 |  |  |    .. versionchanged:: 3.5.1
 | 
					
						
							| 
									
										
										
										
											2015-09-21 18:06:17 +02:00
										 |  |  |       ``'ssl_object'`` info was added to SSL sockets.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  | ReadTransport
 | 
					
						
							|  |  |  | -------------
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. class:: ReadTransport
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Interface for read-only transports.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. method:: pause_reading()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Pause the receiving end of the transport.  No data will be passed to
 | 
					
						
							| 
									
										
										
										
											2014-03-21 17:17:15 +01:00
										 |  |  |       the protocol's :meth:`data_received` method until :meth:`resume_reading`
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  |       is called.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. method:: resume_reading()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Resume the receiving end.  The protocol's :meth:`data_received` method
 | 
					
						
							|  |  |  |       will be called once again if some data is available for reading.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  | WriteTransport
 | 
					
						
							|  |  |  | --------------
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. class:: WriteTransport
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Interface for write-only transports.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. method:: abort()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Close the transport immediately, without waiting for pending operations
 | 
					
						
							|  |  |  |       to complete.  Buffered data will be lost.  No more data will be received.
 | 
					
						
							|  |  |  |       The protocol's :meth:`connection_lost` method will eventually be
 | 
					
						
							|  |  |  |       called with :const:`None` as its argument.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. method:: can_write_eof()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Return :const:`True` if the transport supports :meth:`write_eof`,
 | 
					
						
							|  |  |  |       :const:`False` if not.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. method:: get_write_buffer_size()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Return the current size of the output buffer used by the transport.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-26 00:22:28 +02:00
										 |  |  |    .. method:: get_write_buffer_limits()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Get the *high*- and *low*-water limits for write flow control. Return a
 | 
					
						
							|  |  |  |       tuple ``(low, high)`` where *low* and *high* are positive number of
 | 
					
						
							|  |  |  |       bytes.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Use :meth:`set_write_buffer_limits` to set the limits.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       .. versionadded:: 3.4.2
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  |    .. method:: set_write_buffer_limits(high=None, low=None)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Set the *high*- and *low*-water limits for write flow control.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       These two values control when call the protocol's
 | 
					
						
							|  |  |  |       :meth:`pause_writing` and :meth:`resume_writing` methods are called.
 | 
					
						
							|  |  |  |       If specified, the low-water limit must be less than or equal to the
 | 
					
						
							|  |  |  |       high-water limit.  Neither *high* nor *low* can be negative.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       The defaults are implementation-specific.  If only the
 | 
					
						
							| 
									
										
										
										
											2015-11-02 14:10:23 +02:00
										 |  |  |       high-water limit is given, the low-water limit defaults to an
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  |       implementation-specific value less than or equal to the
 | 
					
						
							|  |  |  |       high-water limit.  Setting *high* to zero forces *low* to zero as
 | 
					
						
							|  |  |  |       well, and causes :meth:`pause_writing` to be called whenever the
 | 
					
						
							|  |  |  |       buffer becomes non-empty.  Setting *low* to zero causes
 | 
					
						
							|  |  |  |       :meth:`resume_writing` to be called only once the buffer is empty.
 | 
					
						
							|  |  |  |       Use of zero for either limit is generally sub-optimal as it
 | 
					
						
							|  |  |  |       reduces opportunities for doing I/O and computation
 | 
					
						
							|  |  |  |       concurrently.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-26 00:22:28 +02:00
										 |  |  |       Use :meth:`get_write_buffer_limits` to get the limits.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  |    .. method:: write(data)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Write some *data* bytes to the transport.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       This method does not block; it buffers the data and arranges for it
 | 
					
						
							|  |  |  |       to be sent out asynchronously.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. method:: writelines(list_of_data)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Write a list (or any iterable) of data bytes to the transport.
 | 
					
						
							|  |  |  |       This is functionally equivalent to calling :meth:`write` on each
 | 
					
						
							|  |  |  |       element yielded by the iterable, but may be implemented more efficiently.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. method:: write_eof()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Close the write end of the transport after flushing buffered data.
 | 
					
						
							|  |  |  |       Data may still be received.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       This method can raise :exc:`NotImplementedError` if the transport
 | 
					
						
							|  |  |  |       (e.g. SSL) doesn't support half-closes.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  | DatagramTransport
 | 
					
						
							|  |  |  | -----------------
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. method:: DatagramTransport.sendto(data, addr=None)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Send the *data* bytes to the remote peer given by *addr* (a
 | 
					
						
							|  |  |  |    transport-dependent target address).  If *addr* is :const:`None`, the
 | 
					
						
							|  |  |  |    data is sent to the target address given on transport creation.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This method does not block; it buffers the data and arranges for it
 | 
					
						
							|  |  |  |    to be sent out asynchronously.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: DatagramTransport.abort()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Close the transport immediately, without waiting for pending operations
 | 
					
						
							|  |  |  |    to complete.  Buffered data will be lost.  No more data will be received.
 | 
					
						
							|  |  |  |    The protocol's :meth:`connection_lost` method will eventually be
 | 
					
						
							|  |  |  |    called with :const:`None` as its argument.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  | BaseSubprocessTransport
 | 
					
						
							|  |  |  | -----------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. class:: BaseSubprocessTransport
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. method:: get_pid()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Return the subprocess process id as an integer.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. method:: get_pipe_transport(fd)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-08 18:36:14 -06:00
										 |  |  |       Return the transport for the communication pipe corresponding to the
 | 
					
						
							| 
									
										
										
										
											2014-10-13 23:56:43 +02:00
										 |  |  |       integer file descriptor *fd*:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       * ``0``: readable streaming transport of the standard input (*stdin*),
 | 
					
						
							|  |  |  |         or :const:`None` if the subprocess was not created with ``stdin=PIPE``
 | 
					
						
							|  |  |  |       * ``1``: writable streaming transport of the standard output (*stdout*),
 | 
					
						
							|  |  |  |         or :const:`None` if the subprocess was not created with ``stdout=PIPE``
 | 
					
						
							|  |  |  |       * ``2``: writable streaming transport of the standard error (*stderr*),
 | 
					
						
							|  |  |  |         or :const:`None` if the subprocess was not created with ``stderr=PIPE``
 | 
					
						
							|  |  |  |       * other *fd*: :const:`None`
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:59:38 +01:00
										 |  |  |    .. method:: get_returncode()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Return the subprocess returncode as an integer or :const:`None`
 | 
					
						
							|  |  |  |       if it hasn't returned, similarly to the
 | 
					
						
							|  |  |  |       :attr:`subprocess.Popen.returncode` attribute.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. method:: kill(self)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-10 10:36:22 +00:00
										 |  |  |       Kill the subprocess, as in :meth:`subprocess.Popen.kill`.
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:59:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       On POSIX systems, the function sends SIGKILL to the subprocess.
 | 
					
						
							|  |  |  |       On Windows, this method is an alias for :meth:`terminate`.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  |    .. method:: send_signal(signal)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Send the *signal* number to the subprocess, as in
 | 
					
						
							|  |  |  |       :meth:`subprocess.Popen.send_signal`.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. method:: terminate()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Ask the subprocess to stop, as in :meth:`subprocess.Popen.terminate`.
 | 
					
						
							|  |  |  |       This method is an alias for the :meth:`close` method.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       On POSIX systems, this method sends SIGTERM to the subprocess.
 | 
					
						
							|  |  |  |       On Windows, the Windows API function TerminateProcess() is called to
 | 
					
						
							|  |  |  |       stop the subprocess.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-13 23:56:43 +02:00
										 |  |  |    .. method:: close()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Ask the subprocess to stop by calling the :meth:`terminate` method if the
 | 
					
						
							|  |  |  |       subprocess hasn't returned yet, and close transports of all pipes
 | 
					
						
							|  |  |  |       (*stdin*, *stdout* and *stderr*).
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-02 15:03:02 +01:00
										 |  |  | .. _asyncio-protocol:
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | Protocols
 | 
					
						
							|  |  |  | =========
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :mod:`asyncio` provides base classes that you can subclass to implement
 | 
					
						
							|  |  |  | your network protocols.  Those classes are used in conjunction with
 | 
					
						
							| 
									
										
										
										
											2014-02-02 15:03:02 +01:00
										 |  |  | :ref:`transports <asyncio-transport>` (see below): the protocol parses incoming
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | data and asks for the writing of outgoing data, while the transport is
 | 
					
						
							|  |  |  | responsible for the actual I/O and buffering.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When subclassing a protocol class, it is recommended you override certain
 | 
					
						
							|  |  |  | methods.  Those methods are callbacks: they will be called by the transport
 | 
					
						
							|  |  |  | on certain events (for example when some data is received); you shouldn't
 | 
					
						
							|  |  |  | call them yourself, unless you are implementing a transport.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. note::
 | 
					
						
							|  |  |  |    All callbacks have default implementations, which are empty.  Therefore,
 | 
					
						
							|  |  |  |    you only need to implement the callbacks for the events in which you
 | 
					
						
							|  |  |  |    are interested.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Protocol classes
 | 
					
						
							|  |  |  | ----------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. class:: Protocol
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The base class for implementing streaming protocols (for use with
 | 
					
						
							|  |  |  |    e.g. TCP and SSL transports).
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. class:: DatagramProtocol
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The base class for implementing datagram protocols (for use with
 | 
					
						
							|  |  |  |    e.g. UDP transports).
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. class:: SubprocessProtocol
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The base class for implementing protocols communicating with child
 | 
					
						
							|  |  |  |    processes (through a set of unidirectional pipes).
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Connection callbacks
 | 
					
						
							|  |  |  | --------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-10 09:19:26 +02:00
										 |  |  | These callbacks may be called on :class:`Protocol`, :class:`DatagramProtocol`
 | 
					
						
							|  |  |  | and :class:`SubprocessProtocol` instances:
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. method:: BaseProtocol.connection_made(transport)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Called when a connection is made.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The *transport* argument is the transport representing the
 | 
					
						
							|  |  |  |    connection.  You are responsible for storing it somewhere
 | 
					
						
							|  |  |  |    (e.g. as an attribute) if you need to.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: BaseProtocol.connection_lost(exc)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Called when the connection is lost or closed.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The argument is either an exception object or :const:`None`.
 | 
					
						
							|  |  |  |    The latter means a regular EOF is received, or the connection was
 | 
					
						
							|  |  |  |    aborted or closed by this side of the connection.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-10 09:19:26 +02:00
										 |  |  | :meth:`~BaseProtocol.connection_made` and :meth:`~BaseProtocol.connection_lost`
 | 
					
						
							|  |  |  | are called exactly once per successful connection.  All other callbacks will be
 | 
					
						
							|  |  |  | called between those two methods, which allows for easier resource management
 | 
					
						
							|  |  |  | in your protocol implementation.
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | The following callbacks may be called only on :class:`SubprocessProtocol`
 | 
					
						
							|  |  |  | instances:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: SubprocessProtocol.pipe_data_received(fd, data)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Called when the child process writes data into its stdout or stderr pipe.
 | 
					
						
							|  |  |  |    *fd* is the integer file descriptor of the pipe.  *data* is a non-empty
 | 
					
						
							|  |  |  |    bytes object containing the data.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: SubprocessProtocol.pipe_connection_lost(fd, exc)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Called when one of the pipes communicating with the child process
 | 
					
						
							|  |  |  |    is closed.  *fd* is the integer file descriptor that was closed.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: SubprocessProtocol.process_exited()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Called when the child process has exited.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Streaming protocols
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  | -------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | The following callbacks are called on :class:`Protocol` instances:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: Protocol.data_received(data)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Called when some data is received.  *data* is a non-empty bytes object
 | 
					
						
							|  |  |  |    containing the incoming data.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. note::
 | 
					
						
							|  |  |  |       Whether the data is buffered, chunked or reassembled depends on
 | 
					
						
							|  |  |  |       the transport.  In general, you shouldn't rely on specific semantics
 | 
					
						
							|  |  |  |       and instead make your parsing generic and flexible enough.  However,
 | 
					
						
							|  |  |  |       data is always received in the correct order.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: Protocol.eof_received()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Calls when the other end signals it won't send any more data
 | 
					
						
							|  |  |  |    (for example by calling :meth:`write_eof`, if the other end also uses
 | 
					
						
							|  |  |  |    asyncio).
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This method may return a false value (including None), in which case
 | 
					
						
							|  |  |  |    the transport will close itself.  Conversely, if this method returns a
 | 
					
						
							|  |  |  |    true value, closing the transport is up to the protocol.  Since the
 | 
					
						
							|  |  |  |    default implementation returns None, it implicitly closes the connection.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. note::
 | 
					
						
							|  |  |  |       Some transports such as SSL don't support half-closed connections,
 | 
					
						
							|  |  |  |       in which case returning true from this method will not prevent closing
 | 
					
						
							|  |  |  |       the connection.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :meth:`data_received` can be called an arbitrary number of times during
 | 
					
						
							|  |  |  | a connection.  However, :meth:`eof_received` is called at most once
 | 
					
						
							|  |  |  | and, if called, :meth:`data_received` won't be called after it.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-29 13:33:15 +01:00
										 |  |  | State machine:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     start -> :meth:`~BaseProtocol.connection_made`
 | 
					
						
							|  |  |  |     [-> :meth:`~Protocol.data_received` \*]
 | 
					
						
							|  |  |  |     [-> :meth:`~Protocol.eof_received` ?]
 | 
					
						
							|  |  |  |     -> :meth:`~BaseProtocol.connection_lost` -> end
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | Datagram protocols
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  | ------------------
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | The following callbacks are called on :class:`DatagramProtocol` instances.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: DatagramProtocol.datagram_received(data, addr)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Called when a datagram is received.  *data* is a bytes object containing
 | 
					
						
							|  |  |  |    the incoming data.  *addr* is the address of the peer sending the data;
 | 
					
						
							|  |  |  |    the exact format depends on the transport.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: DatagramProtocol.error_received(exc)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Called when a previous send or receive operation raises an
 | 
					
						
							|  |  |  |    :class:`OSError`.  *exc* is the :class:`OSError` instance.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This method is called in rare conditions, when the transport (e.g. UDP)
 | 
					
						
							|  |  |  |    detects that a datagram couldn't be delivered to its recipient.
 | 
					
						
							|  |  |  |    In many conditions though, undeliverable datagrams will be silently
 | 
					
						
							|  |  |  |    dropped.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Flow control callbacks
 | 
					
						
							|  |  |  | ----------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-15 21:13:56 -07:00
										 |  |  | These callbacks may be called on :class:`Protocol`,
 | 
					
						
							|  |  |  | :class:`DatagramProtocol` and :class:`SubprocessProtocol` instances:
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. method:: BaseProtocol.pause_writing()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Called when the transport's buffer goes over the high-water mark.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: BaseProtocol.resume_writing()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Called when the transport's buffer drains below the low-water mark.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :meth:`pause_writing` and :meth:`resume_writing` calls are paired --
 | 
					
						
							|  |  |  | :meth:`pause_writing` is called once when the buffer goes strictly over
 | 
					
						
							|  |  |  | the high-water mark (even if subsequent writes increases the buffer size
 | 
					
						
							|  |  |  | even more), and eventually :meth:`resume_writing` is called once when the
 | 
					
						
							|  |  |  | buffer size reaches the low-water mark.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. note::
 | 
					
						
							|  |  |  |    If the buffer size equals the high-water mark,
 | 
					
						
							|  |  |  |    :meth:`pause_writing` is not called -- it must go strictly over.
 | 
					
						
							|  |  |  |    Conversely, :meth:`resume_writing` is called when the buffer size is
 | 
					
						
							|  |  |  |    equal or lower than the low-water mark.  These end conditions
 | 
					
						
							|  |  |  |    are important to ensure that things go as expected when either
 | 
					
						
							|  |  |  |    mark is zero.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-15 21:13:56 -07:00
										 |  |  | .. note::
 | 
					
						
							|  |  |  |    On BSD systems (OS X, FreeBSD, etc.) flow control is not supported
 | 
					
						
							|  |  |  |    for :class:`DatagramProtocol`, because send failures caused by
 | 
					
						
							|  |  |  |    writing too many packets cannot be detected easily.  The socket
 | 
					
						
							|  |  |  |    always appears 'ready' and excess packets are dropped; an
 | 
					
						
							|  |  |  |    :class:`OSError` with errno set to :const:`errno.ENOBUFS` may or
 | 
					
						
							|  |  |  |    may not be raised; if it is raised, it will be reported to
 | 
					
						
							|  |  |  |    :meth:`DatagramProtocol.error_received` but otherwise ignored.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-24 17:33:20 +01:00
										 |  |  | Coroutines and protocols
 | 
					
						
							|  |  |  | ------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-30 22:13:22 -04:00
										 |  |  | Coroutines can be scheduled in a protocol method using :func:`ensure_future`,
 | 
					
						
							|  |  |  | but there is no guarantee made about the execution order.  Protocols are not
 | 
					
						
							|  |  |  | aware of coroutines created in protocol methods and so will not wait for them.
 | 
					
						
							| 
									
										
										
										
											2014-01-24 17:33:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-02 15:03:02 +01:00
										 |  |  | To have a reliable execution order, use :ref:`stream objects <asyncio-streams>` in a
 | 
					
						
							| 
									
										
										
										
											2014-01-24 17:33:20 +01:00
										 |  |  | coroutine with ``yield from``. For example, the :meth:`StreamWriter.drain`
 | 
					
						
							|  |  |  | coroutine can be used to wait until the write buffer is flushed.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-11 16:16:27 +02:00
										 |  |  | Protocol examples
 | 
					
						
							|  |  |  | =================
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-12 20:18:16 +02:00
										 |  |  | .. _asyncio-tcp-echo-client-protocol:
 | 
					
						
							| 
									
										
										
										
											2013-12-09 13:19:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-12 20:18:16 +02:00
										 |  |  | TCP echo client protocol
 | 
					
						
							|  |  |  | ------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-08 09:41:21 -07:00
										 |  |  | TCP echo client  using the :meth:`AbstractEventLoop.create_connection` method, send
 | 
					
						
							| 
									
										
										
										
											2014-10-12 20:18:16 +02:00
										 |  |  | data and wait until the connection is closed::
 | 
					
						
							| 
									
										
										
										
											2013-12-09 13:19:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     import asyncio
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:30:17 +02:00
										 |  |  |     class EchoClientProtocol(asyncio.Protocol):
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:35:09 +02:00
										 |  |  |         def __init__(self, message, loop):
 | 
					
						
							|  |  |  |             self.message = message
 | 
					
						
							|  |  |  |             self.loop = loop
 | 
					
						
							| 
									
										
										
										
											2013-12-09 13:19:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def connection_made(self, transport):
 | 
					
						
							|  |  |  |             transport.write(self.message.encode())
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:35:09 +02:00
										 |  |  |             print('Data sent: {!r}'.format(self.message))
 | 
					
						
							| 
									
										
										
										
											2013-12-09 13:19:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def data_received(self, data):
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:35:09 +02:00
										 |  |  |             print('Data received: {!r}'.format(data.decode()))
 | 
					
						
							| 
									
										
										
										
											2013-12-09 13:19:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def connection_lost(self, exc):
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:35:09 +02:00
										 |  |  |             print('The server closed the connection')
 | 
					
						
							| 
									
										
										
										
											2015-11-19 13:28:47 -08:00
										 |  |  |             print('Stop the event loop')
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:35:09 +02:00
										 |  |  |             self.loop.stop()
 | 
					
						
							| 
									
										
										
										
											2013-12-09 13:19:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     loop = asyncio.get_event_loop()
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:35:09 +02:00
										 |  |  |     message = 'Hello World!'
 | 
					
						
							|  |  |  |     coro = loop.create_connection(lambda: EchoClientProtocol(message, loop),
 | 
					
						
							|  |  |  |                                   '127.0.0.1', 8888)
 | 
					
						
							| 
									
										
										
										
											2013-12-09 13:19:23 +01:00
										 |  |  |     loop.run_until_complete(coro)
 | 
					
						
							|  |  |  |     loop.run_forever()
 | 
					
						
							|  |  |  |     loop.close()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The event loop is running twice. The
 | 
					
						
							| 
									
										
										
										
											2016-08-08 09:41:21 -07:00
										 |  |  | :meth:`~AbstractEventLoop.run_until_complete` method is preferred in this short
 | 
					
						
							| 
									
										
										
										
											2013-12-09 13:19:23 +01:00
										 |  |  | example to raise an exception if the server is not listening, instead of
 | 
					
						
							|  |  |  | having to write a short coroutine to handle the exception and stop the
 | 
					
						
							| 
									
										
										
										
											2016-08-08 09:41:21 -07:00
										 |  |  | running loop. At :meth:`~AbstractEventLoop.run_until_complete` exit, the loop is
 | 
					
						
							| 
									
										
										
										
											2014-07-23 11:27:17 +03:00
										 |  |  | no longer running, so there is no need to stop the loop in case of an error.
 | 
					
						
							| 
									
										
										
										
											2013-12-09 13:19:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-12 20:18:16 +02:00
										 |  |  | .. seealso::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The :ref:`TCP echo client using streams <asyncio-tcp-echo-client-streams>`
 | 
					
						
							|  |  |  |    example uses the :func:`asyncio.open_connection` function.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:13:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-12 20:18:16 +02:00
										 |  |  | .. _asyncio-tcp-echo-server-protocol:
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-12 20:18:16 +02:00
										 |  |  | TCP echo server protocol
 | 
					
						
							|  |  |  | ------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-08 09:41:21 -07:00
										 |  |  | TCP echo server using the :meth:`AbstractEventLoop.create_server` method, send back
 | 
					
						
							| 
									
										
										
										
											2014-10-12 20:18:16 +02:00
										 |  |  | received data and close the connection::
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     import asyncio
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:30:17 +02:00
										 |  |  |     class EchoServerClientProtocol(asyncio.Protocol):
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  |         def connection_made(self, transport):
 | 
					
						
							| 
									
										
										
										
											2013-12-04 11:16:17 +01:00
										 |  |  |             peername = transport.get_extra_info('peername')
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:13:40 +02:00
										 |  |  |             print('Connection from {}'.format(peername))
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  |             self.transport = transport
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def data_received(self, data):
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:13:40 +02:00
										 |  |  |             message = data.decode()
 | 
					
						
							|  |  |  |             print('Data received: {!r}'.format(message))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             print('Send: {!r}'.format(message))
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  |             self.transport.write(data)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:35:09 +02:00
										 |  |  |             print('Close the client socket')
 | 
					
						
							| 
									
										
										
										
											2013-12-03 15:04:18 +01:00
										 |  |  |             self.transport.close()
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:46:39 +01:00
										 |  |  |     loop = asyncio.get_event_loop()
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:30:17 +02:00
										 |  |  |     # Each client connection will create a new protocol instance
 | 
					
						
							|  |  |  |     coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8888)
 | 
					
						
							| 
									
										
										
										
											2013-12-09 13:19:23 +01:00
										 |  |  |     server = loop.run_until_complete(coro)
 | 
					
						
							| 
									
										
										
										
											2013-12-04 11:16:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-12 17:45:25 +03:00
										 |  |  |     # Serve requests until Ctrl+C is pressed
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:13:40 +02:00
										 |  |  |     print('Serving on {}'.format(server.sockets[0].getsockname()))
 | 
					
						
							| 
									
										
										
										
											2013-12-04 11:16:17 +01:00
										 |  |  |     try:
 | 
					
						
							|  |  |  |         loop.run_forever()
 | 
					
						
							|  |  |  |     except KeyboardInterrupt:
 | 
					
						
							| 
									
										
										
										
											2014-10-12 20:18:16 +02:00
										 |  |  |         pass
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:13:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Close the server
 | 
					
						
							|  |  |  |     server.close()
 | 
					
						
							|  |  |  |     loop.run_until_complete(server.wait_closed())
 | 
					
						
							|  |  |  |     loop.close()
 | 
					
						
							| 
									
										
										
										
											2013-12-04 11:16:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-14 11:26:06 -05:00
										 |  |  | :meth:`Transport.close` can be called immediately after
 | 
					
						
							| 
									
										
										
										
											2013-12-04 11:16:17 +01:00
										 |  |  | :meth:`WriteTransport.write` even if data are not sent yet on the socket: both
 | 
					
						
							|  |  |  | methods are asynchronous. ``yield from`` is not needed because these transport
 | 
					
						
							| 
									
										
										
										
											2014-03-15 21:13:56 -07:00
										 |  |  | methods are not coroutines.
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-12 20:18:16 +02:00
										 |  |  | .. seealso::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The :ref:`TCP echo server using streams <asyncio-tcp-echo-server-streams>`
 | 
					
						
							|  |  |  |    example uses the :func:`asyncio.start_server` function.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:24:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. _asyncio-udp-echo-client-protocol:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | UDP echo client protocol
 | 
					
						
							|  |  |  | ------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-08 09:41:21 -07:00
										 |  |  | UDP echo client using the :meth:`AbstractEventLoop.create_datagram_endpoint`
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:24:26 +02:00
										 |  |  | method, send data and close the transport when we received the answer::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     import asyncio
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class EchoClientProtocol:
 | 
					
						
							|  |  |  |         def __init__(self, message, loop):
 | 
					
						
							|  |  |  |             self.message = message
 | 
					
						
							|  |  |  |             self.loop = loop
 | 
					
						
							|  |  |  |             self.transport = None
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def connection_made(self, transport):
 | 
					
						
							|  |  |  |             self.transport = transport
 | 
					
						
							|  |  |  |             print('Send:', self.message)
 | 
					
						
							|  |  |  |             self.transport.sendto(self.message.encode())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def datagram_received(self, data, addr):
 | 
					
						
							|  |  |  |             print("Received:", data.decode())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             print("Close the socket")
 | 
					
						
							|  |  |  |             self.transport.close()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def error_received(self, exc):
 | 
					
						
							|  |  |  |             print('Error received:', exc)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def connection_lost(self, exc):
 | 
					
						
							|  |  |  |             print("Socket closed, stop the event loop")
 | 
					
						
							|  |  |  |             loop = asyncio.get_event_loop()
 | 
					
						
							|  |  |  |             loop.stop()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     loop = asyncio.get_event_loop()
 | 
					
						
							|  |  |  |     message = "Hello World!"
 | 
					
						
							|  |  |  |     connect = loop.create_datagram_endpoint(
 | 
					
						
							|  |  |  |         lambda: EchoClientProtocol(message, loop),
 | 
					
						
							|  |  |  |         remote_addr=('127.0.0.1', 9999))
 | 
					
						
							|  |  |  |     transport, protocol = loop.run_until_complete(connect)
 | 
					
						
							|  |  |  |     loop.run_forever()
 | 
					
						
							|  |  |  |     transport.close()
 | 
					
						
							|  |  |  |     loop.close()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. _asyncio-udp-echo-server-protocol:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | UDP echo server protocol
 | 
					
						
							|  |  |  | ------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-08 09:41:21 -07:00
										 |  |  | UDP echo server using the :meth:`AbstractEventLoop.create_datagram_endpoint`
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:24:26 +02:00
										 |  |  | method, send back received data::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     import asyncio
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:30:17 +02:00
										 |  |  |     class EchoServerProtocol:
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:24:26 +02:00
										 |  |  |         def connection_made(self, transport):
 | 
					
						
							|  |  |  |             self.transport = transport
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def datagram_received(self, data, addr):
 | 
					
						
							|  |  |  |             message = data.decode()
 | 
					
						
							|  |  |  |             print('Received %r from %s' % (message, addr))
 | 
					
						
							|  |  |  |             print('Send %r to %s' % (message, addr))
 | 
					
						
							|  |  |  |             self.transport.sendto(data, addr)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     loop = asyncio.get_event_loop()
 | 
					
						
							|  |  |  |     print("Starting UDP server")
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:30:17 +02:00
										 |  |  |     # One protocol instance will be created to serve all client requests
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:24:26 +02:00
										 |  |  |     listen = loop.create_datagram_endpoint(
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:30:17 +02:00
										 |  |  |         EchoServerProtocol, local_addr=('127.0.0.1', 9999))
 | 
					
						
							| 
									
										
										
										
											2014-10-12 11:24:26 +02:00
										 |  |  |     transport, protocol = loop.run_until_complete(listen)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try:
 | 
					
						
							|  |  |  |         loop.run_forever()
 | 
					
						
							|  |  |  |     except KeyboardInterrupt:
 | 
					
						
							|  |  |  |         pass
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     transport.close()
 | 
					
						
							|  |  |  |     loop.close()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-11 16:16:27 +02:00
										 |  |  | .. _asyncio-register-socket:
 | 
					
						
							| 
									
										
										
										
											2013-12-03 01:08:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-11 16:16:27 +02:00
										 |  |  | Register an open socket to wait for data using a protocol
 | 
					
						
							|  |  |  | ---------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Wait until a socket receives data using the
 | 
					
						
							| 
									
										
										
										
											2016-08-08 09:41:21 -07:00
										 |  |  | :meth:`AbstractEventLoop.create_connection` method with a protocol, and then close
 | 
					
						
							| 
									
										
										
										
											2014-10-11 16:16:27 +02:00
										 |  |  | the event loop ::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     import asyncio
 | 
					
						
							| 
									
										
										
										
											2014-10-11 16:30:02 +02:00
										 |  |  |     try:
 | 
					
						
							|  |  |  |         from socket import socketpair
 | 
					
						
							|  |  |  |     except ImportError:
 | 
					
						
							|  |  |  |         from asyncio.windows_utils import socketpair
 | 
					
						
							| 
									
										
										
										
											2014-10-11 16:16:27 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Create a pair of connected sockets
 | 
					
						
							| 
									
										
										
										
											2014-10-11 16:30:02 +02:00
										 |  |  |     rsock, wsock = socketpair()
 | 
					
						
							| 
									
										
										
										
											2014-10-11 16:16:27 +02:00
										 |  |  |     loop = asyncio.get_event_loop()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class MyProtocol(asyncio.Protocol):
 | 
					
						
							|  |  |  |         transport = None
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def connection_made(self, transport):
 | 
					
						
							|  |  |  |             self.transport = transport
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def data_received(self, data):
 | 
					
						
							|  |  |  |             print("Received:", data.decode())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # We are done: close the transport (it will call connection_lost())
 | 
					
						
							|  |  |  |             self.transport.close()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def connection_lost(self, exc):
 | 
					
						
							|  |  |  |             # The socket has been closed, stop the event loop
 | 
					
						
							|  |  |  |             loop.stop()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Register the socket to wait for data
 | 
					
						
							|  |  |  |     connect_coro = loop.create_connection(MyProtocol, sock=rsock)
 | 
					
						
							|  |  |  |     transport, protocol = loop.run_until_complete(connect_coro)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Simulate the reception of data from the network
 | 
					
						
							|  |  |  |     loop.call_soon(wsock.send, 'abc'.encode())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Run the event loop
 | 
					
						
							|  |  |  |     loop.run_forever()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # We are done, close sockets and the event loop
 | 
					
						
							|  |  |  |     rsock.close()
 | 
					
						
							|  |  |  |     wsock.close()
 | 
					
						
							|  |  |  |     loop.close()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. seealso::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The :ref:`watch a file descriptor for read events
 | 
					
						
							|  |  |  |    <asyncio-watch-read-event>` example uses the low-level
 | 
					
						
							| 
									
										
										
										
											2016-08-08 09:41:21 -07:00
										 |  |  |    :meth:`AbstractEventLoop.add_reader` method to register the file descriptor of a
 | 
					
						
							| 
									
										
										
										
											2014-10-11 16:16:27 +02:00
										 |  |  |    socket.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The :ref:`register an open socket to wait for data using streams
 | 
					
						
							|  |  |  |    <asyncio-register-socket-streams>` example uses high-level streams
 | 
					
						
							|  |  |  |    created by the :func:`open_connection` function in a coroutine.
 |