]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Add TCP echo demo
authorMichael V. DePalatis <mike@depalatis.net>
Wed, 10 Aug 2016 19:55:55 +0000 (21:55 +0200)
committerMichael V. DePalatis <mike@depalatis.net>
Fri, 12 Aug 2016 06:27:04 +0000 (08:27 +0200)
demos/tcpecho/README [new file with mode: 0644]
demos/tcpecho/client.py [new file with mode: 0644]
demos/tcpecho/server.py [new file with mode: 0644]

diff --git a/demos/tcpecho/README b/demos/tcpecho/README
new file mode 100644 (file)
index 0000000..60d0b70
--- /dev/null
@@ -0,0 +1,30 @@
+TCP echo demo
+=============
+
+This demo shows how to use Tornado's asynchronous TCP client and
+server by implementing `handle_stream` as a coroutine.
+
+To run the server:
+
+```
+$ python server.py
+```
+
+The client will send the message given with the `--message` option
+(which defaults to "ping"), wait for a response, then quit. To run:
+
+```
+$ python client.py --message="your message here"
+```
+
+Alternatively, you can interactively send messages to the echo server
+with a telnet client. For example:
+
+```
+$ telnet localhost 9888
+Trying ::1...
+Connected to localhost.
+Escape character is '^]'.
+ping
+ping
+```
diff --git a/demos/tcpecho/client.py b/demos/tcpecho/client.py
new file mode 100644 (file)
index 0000000..a369fa4
--- /dev/null
@@ -0,0 +1,23 @@
+from __future__ import print_function
+from tornado.ioloop import IOLoop
+from tornado import gen
+from tornado.tcpclient import TCPClient
+from tornado.options import options, define
+
+define("host", default="localhost", help="TCP server host")
+define("port", default=9888, help="TCP port to connect to")
+define("message", default="ping", help="Message to send")
+
+
+@gen.coroutine
+def send_message():
+    stream = yield TCPClient().connect(options.host, options.port)
+    yield stream.write((options.message + "\n").encode())
+    print("Sent to server:", options.message)
+    reply = yield stream.read_until(b"\n")
+    print("Response from server:", reply.decode().strip())
+
+
+if __name__ == "__main__":
+    options.parse_command_line()
+    IOLoop.current().run_sync(send_message)
diff --git a/demos/tcpecho/server.py b/demos/tcpecho/server.py
new file mode 100644 (file)
index 0000000..369482f
--- /dev/null
@@ -0,0 +1,37 @@
+import logging
+from tornado.ioloop import IOLoop
+from tornado import gen
+from tornado.iostream import StreamClosedError
+from tornado.tcpserver import TCPServer
+from tornado.options import options, define
+
+define("port", default=9888, help="TCP port to listen on")
+clients = set()
+logger = logging.getLogger(__name__)
+
+
+class EchoServer(TCPServer):
+    @gen.coroutine
+    def handle_stream(self, stream, address):
+        clients.add(address)
+        while True:
+            try:
+                data = yield stream.read_until(b"\n")
+                logger.info("Received bytes: %s", data)
+                if not data.endswith(b"\n"):
+                    data = data + b"\n"
+                yield stream.write(data)
+            except StreamClosedError:
+                clients.remove(address)
+                logger.warning("Lost client at host %s", address[0])
+                break
+            except Exception as e:
+                print(e)
+
+
+if __name__ == "__main__":
+    options.parse_command_line()
+    server = EchoServer()
+    server.listen(options.port)
+    logger.info("Listening on TCP port %d", options.port)
+    IOLoop.current().start()