在这个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分析的更多相关文章

  1. tornado源码分析-iostream

    tornado源码分析-iostream 1.iostream.py作用 用来异步读写文件,socket通信 2.使用示例 import tornado.ioloop import tornado.i ...

  2. Tornado源码分析 --- 静态文件处理模块

    每个web框架都会有对静态文件的处理支持,下面对于Tornado的静态文件的处理模块的源码进行分析,以加强自己对静态文件处理的理解. 先从Tornado的主要模块 web.py 入手,可以看到在App ...

  3. Tornado源码分析系列之一: 化异步为'同步'的Future和gen.coroutine

    转自:http://blog.nathon.wang/2015/06/24/tornado-source-insight-01-gen/ 用Tornado也有一段时间,Tornado的文档还是比较匮乏 ...

  4. Tornado源码分析之http服务器篇

    转载自 http://kenby.iteye.com/blog/1159621 一. Tornado是什么? Facebook发布了开源网络服务器框架Tornado,该平台基于Facebook刚刚收购 ...

  5. tornado源码分析-模块介绍

    1.Core web framework tornado.web - web框架功能模块,包括RequestHandler和Application两个重要的类 tornado.httpserver - ...

  6. Tornado源码分析 --- Cookie和XSRF机制

    Cookie和Session的理解: 具体Cookie的介绍,可以参考:HTTP Cookie详解 可以先查看之前的一篇文章:Tornado的Cookie过期问题 XSRF跨域请求伪造(Cross-S ...

  7. Tornado源码分析 --- Redirect重定向

    “重定向”简单介绍: “重定向”指的是HTTP重定向,是HTTP协议的一种机制.当client向server发送一个请求,要求获取一个资源时,在server接收到这个请求后发现请求的这个资源实际存放在 ...

  8. Tornado源码分析 --- Etag实现

    Etag(URL的Entity Tag): 对于具体Etag是什么,请求流程,实现原理,这里不进行介绍,可以参考下面链接: http://www.oschina.net/question/234345 ...

  9. tornado源码分析系列一

    先来看一个简单的示例: #!/usr/bin/env python #coding:utf8 import socket def run(): sock = socket.socket(socket. ...

随机推荐

  1. 深度探索C++对象模型之第一章:关于对象之C++对象模型

    一.C和C++对比: C语言的Point3d: 数据成员定义在结构体之内,存在一组各个以功能为导向的函数中,共同处理外部的数据. typedef struct point3d { float x; f ...

  2. mysql 存储过程学习

    存储过程框架 DEMILITER $$ -- 重定义符 DROP PROCEDURE IF EXISTS store_procedure$$ -- 如果存在此名的存储过程,先删除 CREATE PRO ...

  3. js清空input file值

    项目进行导入操作,如果第一次导入某个文件会触发导入操作,但是第二次导入重复该文件,不会触发操作. 分析了原因,是因为上一次file里选择的文件路径值与本次选择的文件路径值是一样的,值没有改变所以导致f ...

  4. 如何解决nodemon运行报错问题

    原因 nodemon没有被正确安装 解决方法 如果yarn global add nodemon --verbose安装没用的话,然后输入npm i nodemon -g --verbose使用NPM ...

  5. php算法题---对称的二叉树

    php算法题---对称的二叉树 一.总结 一句话总结: 可以在isSymmetrical()的基础上再加一个函数comRoot,函数comRoot来做树的递归判断 /*思路:首先根节点以及其左右子树, ...

  6. Assert(断言) 的用法

    Assert Assert是断言的意思,头文件为assert.h, assert是一个宏 功 能: 测试一个条件并可能使程序终止 用 法: void assert(int test); 在单元测试中经 ...

  7. USART 串口

    串口不工作 请逐一检查: 是否正确配置复用IO口(先用RCC_APB2PeriphClockCmd在RCC寄存器中先开启GPIOx的时钟使能,再用 GPIO_Init 进行IO复用配置) 是否正确配置 ...

  8. PAT甲级——A1133 Splitting A Linked List【25】

    Given a singly linked list, you are supposed to rearrange its elements so that all the negative valu ...

  9. java关键字之instanceof

    首先来看段测试代码 public class TestInstanceof{ public static void main(String[] args){ int a = 1; if(a insta ...

  10. vue2.0装jquery

    1.在项目目录下 cnpm install --save jquery 2.在webpack.base.conf.js中加入 var webpack = require('webpack') 3.在p ...