asyncio doc: write a complete TCP echo example, client and server
Example based on tcp_echo.py example from Tulip source code.
This commit is contained in:
parent
3e09e32c8a
commit
0c6f1ca40c
|
@ -150,7 +150,7 @@ a different clock than :func:`time.time`.
|
|||
|
||||
|
||||
Creating connections
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
--------------------
|
||||
|
||||
.. method:: BaseEventLoop.create_connection(protocol_factory, host=None, port=None, \*, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None)
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ subprocess pipes. The methods available on a transport depend on
|
|||
the transport's kind.
|
||||
|
||||
|
||||
BaseTransport: Methods common to all transports
|
||||
-----------------------------------------------
|
||||
BaseTransport
|
||||
-------------
|
||||
|
||||
.. class:: BaseTransport
|
||||
|
||||
|
@ -75,8 +75,8 @@ BaseTransport: Methods common to all transports
|
|||
- ``'subprocess'``: :class:`subprocess.Popen` instance
|
||||
|
||||
|
||||
ReadTransport: Methods of readable streaming transports
|
||||
-------------------------------------------------------
|
||||
ReadTransport
|
||||
-------------
|
||||
|
||||
.. class:: ReadTransport
|
||||
|
||||
|
@ -94,8 +94,8 @@ ReadTransport: Methods of readable streaming transports
|
|||
will be called once again if some data is available for reading.
|
||||
|
||||
|
||||
WriteTransport: Methods of writable streaming transports
|
||||
--------------------------------------------------------
|
||||
WriteTransport
|
||||
--------------
|
||||
|
||||
.. class:: WriteTransport
|
||||
|
||||
|
@ -159,8 +159,8 @@ WriteTransport: Methods of writable streaming transports
|
|||
(e.g. SSL) doesn't support half-closes.
|
||||
|
||||
|
||||
DatagramTransport: Methods of datagram transports
|
||||
-------------------------------------------------
|
||||
DatagramTransport
|
||||
-----------------
|
||||
|
||||
.. method:: DatagramTransport.sendto(data, addr=None)
|
||||
|
||||
|
@ -179,8 +179,8 @@ DatagramTransport: Methods of datagram transports
|
|||
called with :const:`None` as its argument.
|
||||
|
||||
|
||||
Methods of subprocess transports
|
||||
--------------------------------
|
||||
BaseSubprocessTransport
|
||||
-----------------------
|
||||
|
||||
.. class:: BaseSubprocessTransport
|
||||
|
||||
|
@ -224,8 +224,8 @@ Methods of subprocess transports
|
|||
On Windows, this method is an alias for :meth:`terminate`.
|
||||
|
||||
|
||||
Stream reader
|
||||
-------------
|
||||
StreamWriter
|
||||
------------
|
||||
|
||||
.. class:: StreamWriter(transport, protocol, reader, loop)
|
||||
|
||||
|
@ -286,8 +286,8 @@ Stream reader
|
|||
see :meth:`WriteTransport.write_eof`.
|
||||
|
||||
|
||||
Stream writer
|
||||
-------------
|
||||
StreamReader
|
||||
------------
|
||||
|
||||
.. class:: StreamReader(limit=_DEFAULT_LIMIT, loop=None)
|
||||
|
||||
|
@ -418,11 +418,8 @@ instances:
|
|||
Called when the child process has exited.
|
||||
|
||||
|
||||
Data reception callbacks
|
||||
------------------------
|
||||
|
||||
Streaming protocols
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
-------------------
|
||||
|
||||
The following callbacks are called on :class:`Protocol` instances:
|
||||
|
||||
|
@ -458,7 +455,7 @@ a connection. However, :meth:`eof_received` is called at most once
|
|||
and, if called, :meth:`data_received` won't be called after it.
|
||||
|
||||
Datagram protocols
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
------------------
|
||||
|
||||
The following callbacks are called on :class:`DatagramProtocol` instances.
|
||||
|
||||
|
@ -576,15 +573,18 @@ Network functions
|
|||
|
||||
This function returns a :ref:`coroutine <coroutine>`.
|
||||
|
||||
Example: Echo server
|
||||
--------------------
|
||||
|
||||
A :class:`Protocol` implementing an echo server::
|
||||
Protocol example: TCP echo client and server
|
||||
============================================
|
||||
|
||||
Echo server
|
||||
-----------
|
||||
|
||||
TCP echo server example::
|
||||
|
||||
import asyncio
|
||||
|
||||
class EchoServer(asyncio.Protocol):
|
||||
|
||||
TIMEOUT = 5.0
|
||||
|
||||
def timeout(self):
|
||||
print('connection timeout, closing.')
|
||||
self.transport.close()
|
||||
|
@ -593,23 +593,49 @@ A :class:`Protocol` implementing an echo server::
|
|||
print('connection made')
|
||||
self.transport = transport
|
||||
|
||||
# start 5 seconds timeout timer
|
||||
self.h_timeout = asyncio.get_event_loop().call_later(
|
||||
self.TIMEOUT, self.timeout)
|
||||
# close the client connection after 2 seconds
|
||||
asyncio.get_event_loop().call_later(2.0, self.timeout)
|
||||
|
||||
def data_received(self, data):
|
||||
print('data received: ', data.decode())
|
||||
self.transport.write(b'Re: ' + data)
|
||||
|
||||
# restart timeout timer
|
||||
self.h_timeout.cancel()
|
||||
self.h_timeout = asyncio.get_event_loop().call_later(
|
||||
self.TIMEOUT, self.timeout)
|
||||
|
||||
def eof_received(self):
|
||||
pass
|
||||
print('data received:', data.decode())
|
||||
self.transport.write(data)
|
||||
|
||||
def connection_lost(self, exc):
|
||||
print('connection lost:', exc)
|
||||
self.h_timeout.cancel()
|
||||
print('connection lost')
|
||||
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
f = loop.create_server(EchoServer, '127.0.0.1', 8888)
|
||||
s = loop.run_until_complete(f)
|
||||
print('serving on', s.sockets[0].getsockname())
|
||||
loop.run_forever()
|
||||
|
||||
|
||||
Echo client
|
||||
-----------
|
||||
|
||||
TCP echo client example::
|
||||
|
||||
import asyncio
|
||||
|
||||
class EchoClient(asyncio.Protocol):
|
||||
message = 'This is the message. It will be echoed.'
|
||||
|
||||
def connection_made(self, transport):
|
||||
self.transport = transport
|
||||
self.transport.write(self.message.encode())
|
||||
print('data sent:', self.message)
|
||||
|
||||
def data_received(self, data):
|
||||
print('data received:', data.decode())
|
||||
|
||||
def connection_lost(self, exc):
|
||||
print('connection lost')
|
||||
asyncio.get_event_loop().stop()
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
task = loop.create_connection(EchoClient, '127.0.0.1', 8888)
|
||||
loop.run_until_complete(task)
|
||||
loop.run_forever()
|
||||
loop.close()
|
||||
|
||||
|
|
Loading…
Reference in New Issue