博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Tornado demo3 - tcpecho分析
阅读量:5244 次
发布时间:2019-06-14

本文共 4173 字,大约阅读时间需要 13 分钟。

在这个demo中,主要是使用了Tornado中异步的TCP client和server来实现一个简单的echo效果(即客户端发送的message会从server端返回到client)。代码的github链接。

1 Server端代码分析

1 import logging 2 from tornado.ioloop import IOLoop 3 from tornado import gen 4 from tornado.iostream import StreamClosedError 5 from tornado.tcpserver import TCPServer 6 from tornado.options import options, define 7  8 define("port", default=9888, help="TCP port to listen on") 9 logger = logging.getLogger(__name__)10 11 12 class EchoServer(TCPServer):13     @gen.coroutine14     def handle_stream(self, stream, address):15         while True:16             try:17                 data = yield stream.read_until(b"\n")18                 logger.info("Received bytes: %s", data)19                 if not data.endswith(b"\n"):20                     data = data + b"\n"21                 yield stream.write(data)22             except StreamClosedError:23                 logger.warning("Lost client at host %s", address[0])24                 break25             except Exception as e:26                 print(e)27 28 29 if __name__ == "__main__":30     options.parse_command_line()31     server = EchoServer()32     server.listen(options.port)33     logger.info("Listening on TCP port %d", options.port)34     IOLoop.current().start()
server.py

涉及到引入的模块及作用:

import logging   //用来记录日志 from tornado.ioloop import IOLoop from tornado import gen    //实现异步 from tornado.iostream import StreamClosedError   //处理iostream from tornado.tcpserver import TCPServer   // 非阻塞单线程的TCP server及其相关哦功能 from tornado.options import options, define  // options参数相关

server端代码并不复杂,首先定义了默认的监听端口,并且生成了一个logger实例。(logging用法。)

define("port", default=9888, help="TCP port to listen on")logger = logging.getLogger(__name__)

然后创建EchoServer类如下。这个类继承TCPServer(更多)。里面重写了handle_stream方法。handle_stream接收了stream和address两个参数,stream是一个iostream的object,address是client端地址。逻辑比较清晰,使用try, except来捕获io错误,如果没有错误的话,会读取stream内容直到遇到换行停止。读取到的data会写回到client端,通过write(data)。 

 

handle_stream方法是用了@gen.coroutine装饰器和yield来实现异步读取\写回iostream。

class EchoServer(TCPServer):    @gen.coroutine    def handle_stream(self, stream, 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:                logger.warning("Lost client at host %s", address[0])                break            except Exception as e:                print(e)

最后在main部分,生成一个EchoServer实例并监听定义的端口,然后启动事件的ioloop。

options.parse_command_line()server = EchoServer()server.listen(options.port)logger.info("Listening on TCP port %d", options.port)IOLoop.current().start()

 

2 Client端代码分析

1 from __future__ import print_function 2 from tornado.ioloop import IOLoop 3 from tornado import gen 4 from tornado.tcpclient import TCPClient 5 from tornado.options import options, define 6  7 define("host", default="localhost", help="TCP server host") 8 define("port", default=9888, help="TCP port to connect to") 9 define("message", default="ping", help="Message to send")10 11 12 @gen.coroutine13 def send_message():14     stream = yield TCPClient().connect(options.host, options.port)15     yield stream.write((options.message + "\n").encode())16     print("Sent to server:", options.message)17     reply = yield stream.read_until(b"\n")18     print("Response from server:", reply.decode().strip())19 20 21 if __name__ == "__main__":22     options.parse_command_line()23     IOLoop.current().run_sync(send_message)
client.py

client 端首先定义了3个option, host,port,以及message,分别为要连接的服务端的host ip, 端口和要发送的message.

send_message用来向server端发送和接收数据。同样这里使用@gen.coroutine和yield来实现异步。

@gen.coroutinedef 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())

3 运行效果

server端运行后,可以使用运行client.py发送消息,发送完成后连接会端口。也可以使用telnet保持连接,交互式的发送数据给server端。

 

转载于:https://www.cnblogs.com/cedrelaliu/p/5983153.html

你可能感兴趣的文章
网页css效果调试技巧
查看>>
Python【第三课】 函数基础
查看>>
django的日志发往http server
查看>>
Scrapy项目 - 实现斗鱼直播网站信息爬取的爬虫设计
查看>>
音视频学习路线
查看>>
python基础数据类型
查看>>
Sql CLR创建一个简单的表值函数
查看>>
Font Awesome矢量版,十六进制版,WPF字体使用
查看>>
●BZOJ 3512 DZY Loves Math IV
查看>>
act_window 属性
查看>>
Solr4:设计数据结构,就是配置schema.xml
查看>>
Saltstack自动化操作记录(1)-环境部署【转】
查看>>
首发:极简的Centos主机监控方法,分分钟即可使用【转】
查看>>
不老的神器:安全扫描器Nmap渗透使用指南【转】
查看>>
CSS制作彩虹效果
查看>>
多线程和异步操作的异同
查看>>
dotpeek的导出
查看>>
NIO(3)--Selector
查看>>
Objective C, erum 枚举类型
查看>>
5 Logistic回归(二)
查看>>