Kaydet (Commit) 0c6f1ca4 authored tarafından Victor Stinner's avatar Victor Stinner

asyncio doc: write a complete TCP echo example, client and server

Example based on tcp_echo.py example from Tulip source code.
üst 3e09e32c
...@@ -150,7 +150,7 @@ a different clock than :func:`time.time`. ...@@ -150,7 +150,7 @@ a different clock than :func:`time.time`.
Creating connections 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) .. 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 ...@@ -20,8 +20,8 @@ subprocess pipes. The methods available on a transport depend on
the transport's kind. the transport's kind.
BaseTransport: Methods common to all transports BaseTransport
----------------------------------------------- -------------
.. class:: BaseTransport .. class:: BaseTransport
...@@ -75,8 +75,8 @@ BaseTransport: Methods common to all transports ...@@ -75,8 +75,8 @@ BaseTransport: Methods common to all transports
- ``'subprocess'``: :class:`subprocess.Popen` instance - ``'subprocess'``: :class:`subprocess.Popen` instance
ReadTransport: Methods of readable streaming transports ReadTransport
------------------------------------------------------- -------------
.. class:: ReadTransport .. class:: ReadTransport
...@@ -94,8 +94,8 @@ ReadTransport: Methods of readable streaming transports ...@@ -94,8 +94,8 @@ ReadTransport: Methods of readable streaming transports
will be called once again if some data is available for reading. will be called once again if some data is available for reading.
WriteTransport: Methods of writable streaming transports WriteTransport
-------------------------------------------------------- --------------
.. class:: WriteTransport .. class:: WriteTransport
...@@ -159,8 +159,8 @@ WriteTransport: Methods of writable streaming transports ...@@ -159,8 +159,8 @@ WriteTransport: Methods of writable streaming transports
(e.g. SSL) doesn't support half-closes. (e.g. SSL) doesn't support half-closes.
DatagramTransport: Methods of datagram transports DatagramTransport
------------------------------------------------- -----------------
.. method:: DatagramTransport.sendto(data, addr=None) .. method:: DatagramTransport.sendto(data, addr=None)
...@@ -179,8 +179,8 @@ DatagramTransport: Methods of datagram transports ...@@ -179,8 +179,8 @@ DatagramTransport: Methods of datagram transports
called with :const:`None` as its argument. called with :const:`None` as its argument.
Methods of subprocess transports BaseSubprocessTransport
-------------------------------- -----------------------
.. class:: BaseSubprocessTransport .. class:: BaseSubprocessTransport
...@@ -224,8 +224,8 @@ Methods of subprocess transports ...@@ -224,8 +224,8 @@ Methods of subprocess transports
On Windows, this method is an alias for :meth:`terminate`. On Windows, this method is an alias for :meth:`terminate`.
Stream reader StreamWriter
------------- ------------
.. class:: StreamWriter(transport, protocol, reader, loop) .. class:: StreamWriter(transport, protocol, reader, loop)
...@@ -286,8 +286,8 @@ Stream reader ...@@ -286,8 +286,8 @@ Stream reader
see :meth:`WriteTransport.write_eof`. see :meth:`WriteTransport.write_eof`.
Stream writer StreamReader
------------- ------------
.. class:: StreamReader(limit=_DEFAULT_LIMIT, loop=None) .. class:: StreamReader(limit=_DEFAULT_LIMIT, loop=None)
...@@ -418,11 +418,8 @@ instances: ...@@ -418,11 +418,8 @@ instances:
Called when the child process has exited. Called when the child process has exited.
Data reception callbacks
------------------------
Streaming protocols Streaming protocols
^^^^^^^^^^^^^^^^^^^ -------------------
The following callbacks are called on :class:`Protocol` instances: The following callbacks are called on :class:`Protocol` instances:
...@@ -458,7 +455,7 @@ a connection. However, :meth:`eof_received` is called at most once ...@@ -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. and, if called, :meth:`data_received` won't be called after it.
Datagram protocols Datagram protocols
^^^^^^^^^^^^^^^^^^ ------------------
The following callbacks are called on :class:`DatagramProtocol` instances. The following callbacks are called on :class:`DatagramProtocol` instances.
...@@ -576,15 +573,18 @@ Network functions ...@@ -576,15 +573,18 @@ Network functions
This function returns a :ref:`coroutine <coroutine>`. This function returns a :ref:`coroutine <coroutine>`.
Example: Echo server
--------------------
A :class:`Protocol` implementing an echo server:: Protocol example: TCP echo client and server
============================================
class EchoServer(asyncio.Protocol): Echo server
-----------
TCP echo server example::
TIMEOUT = 5.0 import asyncio
class EchoServer(asyncio.Protocol):
def timeout(self): def timeout(self):
print('connection timeout, closing.') print('connection timeout, closing.')
self.transport.close() self.transport.close()
...@@ -593,23 +593,49 @@ A :class:`Protocol` implementing an echo server:: ...@@ -593,23 +593,49 @@ A :class:`Protocol` implementing an echo server::
print('connection made') print('connection made')
self.transport = transport self.transport = transport
# start 5 seconds timeout timer # close the client connection after 2 seconds
self.h_timeout = asyncio.get_event_loop().call_later( asyncio.get_event_loop().call_later(2.0, self.timeout)
self.TIMEOUT, self.timeout)
def data_received(self, data): def data_received(self, data):
print('data received: ', data.decode()) print('data received:', data.decode())
self.transport.write(b'Re: ' + data) self.transport.write(data)
def connection_lost(self, exc):
print('connection lost')
# restart timeout timer
self.h_timeout.cancel()
self.h_timeout = asyncio.get_event_loop().call_later(
self.TIMEOUT, self.timeout)
def eof_received(self): loop = asyncio.get_event_loop()
pass 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): def connection_lost(self, exc):
print('connection lost:', exc) print('connection lost')
self.h_timeout.cancel() 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()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment