]> granicus.if.org Git - python/commitdiff
asyncio doc: write a complete TCP echo example, client and server
authorVictor Stinner <victor.stinner@gmail.com>
Tue, 3 Dec 2013 00:46:39 +0000 (01:46 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Tue, 3 Dec 2013 00:46:39 +0000 (01:46 +0100)
Example based on tcp_echo.py example from Tulip source code.

Doc/library/asyncio-eventloop.rst
Doc/library/asyncio-protocol.rst

index eef9aa1c849460e4747560146de3bcb18802228e..6325f3d24b56a37dc5cbf73a9c2abdf2d52f7960 100644 (file)
@@ -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)
 
index 5b0fdfaf3f43341bbc7164bce3abf8238b1097b9..f3921f5e19222e8f131e476e320003cba3bd1215 100644 (file)
@@ -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,40 +573,69 @@ 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):
+        def timeout(self):
+            print('connection timeout, closing.')
+            self.transport.close()
+
+        def connection_made(self, transport):
+            print('connection made')
+            self.transport = transport
+
+            # 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(data)
+
+        def connection_lost(self, exc):
+            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()
 
-   class EchoServer(asyncio.Protocol):
 
-       TIMEOUT = 5.0
+Echo client
+-----------
 
-       def timeout(self):
-           print('connection timeout, closing.')
-           self.transport.close()
+TCP echo client example::
 
-       def connection_made(self, transport):
-           print('connection made')
-           self.transport = transport
+    import asyncio
 
-           # start 5 seconds timeout timer
-           self.h_timeout = asyncio.get_event_loop().call_later(
-               self.TIMEOUT, self.timeout)
+    class EchoClient(asyncio.Protocol):
+        message = 'This is the message. It will be echoed.'
 
-       def data_received(self, data):
-           print('data received: ', data.decode())
-           self.transport.write(b'Re: ' + data)
+        def connection_made(self, transport):
+            self.transport = transport
+            self.transport.write(self.message.encode())
+            print('data sent:', self.message)
 
-           # restart timeout timer
-           self.h_timeout.cancel()
-           self.h_timeout = asyncio.get_event_loop().call_later(
-               self.TIMEOUT, self.timeout)
+        def data_received(self, data):
+            print('data received:', data.decode())
 
-       def eof_received(self):
-           pass
+        def connection_lost(self, exc):
+            print('connection lost')
+            asyncio.get_event_loop().stop()
 
-       def connection_lost(self, exc):
-           print('connection lost:', exc)
-           self.h_timeout.cancel()
+    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()