Tornado demo3 - tcpecho分析
在这个demo中,主要是使用了Tornado中异步的TCP client和server来实现一个简单的echo效果(即客户端发送的message会从server端返回到client)。代码的github链接点这里。
1 Server端代码分析
- 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")
- logger = logging.getLogger(__name__)
- 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)
- 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()
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端代码分析
- 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)
client.py
client 端首先定义了3个option, host,port,以及message,分别为要连接的服务端的host ip, 端口和要发送的message.
send_message用来向server端发送和接收数据。同样这里使用@gen.coroutine和yield来实现异步。
- @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())
3 运行效果
server端运行后,可以使用运行client.py发送消息,发送完成后连接会端口。也可以使用telnet保持连接,交互式的发送数据给server端。
Tornado demo3 - tcpecho分析的更多相关文章
- tornado源码分析-iostream
tornado源码分析-iostream 1.iostream.py作用 用来异步读写文件,socket通信 2.使用示例 import tornado.ioloop import tornado.i ...
- Tornado源码分析 --- 静态文件处理模块
每个web框架都会有对静态文件的处理支持,下面对于Tornado的静态文件的处理模块的源码进行分析,以加强自己对静态文件处理的理解. 先从Tornado的主要模块 web.py 入手,可以看到在App ...
- Tornado源码分析系列之一: 化异步为'同步'的Future和gen.coroutine
转自:http://blog.nathon.wang/2015/06/24/tornado-source-insight-01-gen/ 用Tornado也有一段时间,Tornado的文档还是比较匮乏 ...
- Tornado源码分析之http服务器篇
转载自 http://kenby.iteye.com/blog/1159621 一. Tornado是什么? Facebook发布了开源网络服务器框架Tornado,该平台基于Facebook刚刚收购 ...
- tornado源码分析-模块介绍
1.Core web framework tornado.web - web框架功能模块,包括RequestHandler和Application两个重要的类 tornado.httpserver - ...
- Tornado源码分析 --- Cookie和XSRF机制
Cookie和Session的理解: 具体Cookie的介绍,可以参考:HTTP Cookie详解 可以先查看之前的一篇文章:Tornado的Cookie过期问题 XSRF跨域请求伪造(Cross-S ...
- Tornado源码分析 --- Redirect重定向
“重定向”简单介绍: “重定向”指的是HTTP重定向,是HTTP协议的一种机制.当client向server发送一个请求,要求获取一个资源时,在server接收到这个请求后发现请求的这个资源实际存放在 ...
- Tornado源码分析 --- Etag实现
Etag(URL的Entity Tag): 对于具体Etag是什么,请求流程,实现原理,这里不进行介绍,可以参考下面链接: http://www.oschina.net/question/234345 ...
- tornado源码分析系列一
先来看一个简单的示例: #!/usr/bin/env python #coding:utf8 import socket def run(): sock = socket.socket(socket. ...
随机推荐
- python包的安装
Microsoft Windows [版本 10.0.17134.228] (c) 2018 Microsoft Corporation.保留所有权利. C:\Users\Administrator& ...
- WIN10安装CUDA10 cuDNN
文章目录 CPU和GPU 什么是CUDA 什么是cuDNN WIN10安装CUDA10 WIN10安装cuDNN CPU和GPU CPU和GPU是不一样的计算机设备,CPU作为计算机心脏一直被人们所认 ...
- Java类加载器浅述
jdk默认提供了三种类加载器: 1.Bootstrap ClassLoader(引导类加载器): 将<JAVA_HOME>\lib目录下的类库加载到虚拟机内存中,用来加载java的核心库, ...
- Java 集群高可用监控(结合阿里SLB)脚本
欢迎点评,大家一起来优化 计划思路: 只有在mysql slave java 进程状态都正常的情况下才允许nginx 运行, 否则就干掉它, 负载用的是阿里的SLB #bin/bash #邮件函数 ...
- 一张图轻松掌握 Flink on YARN 应用启动全流程(上)
Flink 支持 Standalone 独立部署和 YARN.Kubernetes.Mesos 等集群部署模式,其中 YARN 集群部署模式在国内的应用越来越广泛.Flink 社区将推出 Flink ...
- 出现不不能引java.util.Date包的情况
出现不不能引java.util.Date包的情况 那个时间段不能引,IDE的bug,等一会儿就好了 心得:很多时候没必要和bug死磕,因为真的不是你的问题.
- Laravel5.4中自定义404等错误页面
1.在resources/views/下简历文件夹error,在error文件中建立"404.blade.php文件". <!DOCTYPE html PUBLIC &quo ...
- POJ-1502-MPI Maelstrom-dijkstra+输入处理
BIT has recently taken delivery of their new supercomputer, a 32 processor Apollo Odyssey distribute ...
- JVM规范
- [AHOI2014/JSOI2014]骑士游戏
题目 思博贪心题写了一个半小时没救了,我也没看出这是一个\(spfa\)来啊 设\(dp_i\)表示彻底干掉第\(i\)只怪物的最小花费,一个非常显然的事情,就是对于\(k_i\)值最小的怪物满足\( ...