在这个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. redis集群的学习(一)

    redis配置文件详解 redis默认是不作为守护进程来运行的,你可以把这个设置为yes,让它作为守护进程来运行 注意,当作为守护进程的时候,redis 会把进程ID 写到/var/run/redis ...

  2. Flink常用资料网址

    Flink官网https://flink.apache.org/ 阿里flink开发文档 https://help.aliyun.com/product/45029.html?spm=a2c4g.11 ...

  3. hdu多校第四场 1003 (hdu6616) Divide the Stones 机智题

    题意: 给你重量分别为1到n的n个石头,让你分成重量相等,数量也相等的k组,保证k是n的约数.问你能不能分配,如果能,输出具体的分配方案. 题解: 首先,如果1到n之和不能整除k,那么一定不能如题意分 ...

  4. 使用OxyPlot在WPF中创建图表

    目录(?)[+] Using Nuget 包括OxyPlot在你的应用程序的最简单方法是使用NuGet包管理器在Visual Studio 运行 Visual Studio并开始创建一个新的WPF项目 ...

  5. C++函数调用原理理解

    空程序: int main() { 00411360  push        ebp       ;压入ebp 00411361  mov         ebp,esp     ;ebp = es ...

  6. 如何查找一个命令由哪个rpm安装&&rpm 的相关查询方法

    [root@test-can-nginx src]# which python3 /usr/bin/python3 [root@test-can-nginx src]# rpm -qf /usr/bi ...

  7. linux的mysql权限错误导致看不到mysql数据库

    1.首先停止mysql服务:service mysqld stop2.加参数启动mysql:/usr/bin/mysqld_safe --skip-grant-tables & 然后就可以无任 ...

  8. jQuery.event.move

    http://stephband.info/jquery.event.move/ Move events movestart Fired following touchmove or mousemov ...

  9. 关于Android 的网址

    Android 官方API查询网址 https://developer.android.google.cn/ 第三方镜像Android API查询网址 (比官方浏览速度快一些,缺点现有API较低) h ...

  10. 筛法求欧拉函数(poj2478

    求1-n的欧拉函数的值 #include <iostream> #include <cstdio> #include <queue> #include <al ...