From: Michael V. DePalatis Date: Wed, 10 Aug 2016 19:55:55 +0000 (+0200) Subject: Add TCP echo demo X-Git-Tag: v4.5.0~80^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1920c86dd619752665bb34c3a20aa35163a7f05b;p=thirdparty%2Ftornado.git Add TCP echo demo --- diff --git a/demos/tcpecho/README b/demos/tcpecho/README new file mode 100644 index 000000000..60d0b70ca --- /dev/null +++ b/demos/tcpecho/README @@ -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 index 000000000..a369fa474 --- /dev/null +++ b/demos/tcpecho/client.py @@ -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 index 000000000..369482f83 --- /dev/null +++ b/demos/tcpecho/server.py @@ -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()