Tornado demo3 - tcpecho分析

在这个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.coroutine
14     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                 break
25             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 IOLoopfrom tornado import gen    //实现异步from tornado.iostream import StreamClosedError   //处理iostreamfrom 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.coroutine
13 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.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端。

时间: 2024-11-03 21:22:39

Tornado demo3 - tcpecho分析的相关文章

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

转自:http://blog.nathon.wang/2015/06/24/tornado-source-insight-01-gen/ 用Tornado也有一段时间,Tornado的文档还是比较匮乏的,但是幸好其代码短小精悍,很有可读性,遇到问题时总是习惯深入到其源码中.这对于提升自己的Python水平和对于网络及HTTP的协议的理解也很有帮助.本文是Tornado源码系列的第一篇文章,网上关于Tornado源码分析的文章也不少,大多是从Event loop入手,分析Event loop的工作

tornado源码分析系列一

先来看一个简单的示例: #!/usr/bin/env  python #coding:utf8 import socket def run():     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)     sock.bind(('127.0.0.1',8008))     sock.listen(5)          while True:         connection,address = sock.accept()

Tornado源码分析之http服务器篇

一. Tornado是什么? Facebook发布了开源网络服务器框架Tornado,该平台基于Facebook刚刚收购的社交聚合网站FriendFeed的实时信息服务开发而来.Tornado由Python编写,是一款轻量级的Web服务器,同时又是一个开发框架.采用非阻塞I/O模型(epoll),主要是为了应对高并发 访问量而被开发出来,尤其适用于comet应用. 二. 为什么要阅读Tornado的源代码 Tornado由前google员工开发, 代码非常精练, 实现也很轻巧, 加上清晰的注释和

tornado 源码分析 之 异步io的实现方式

前言 本文将尝试详细的带大家一步步走完一个异步操作,从而了解tornado是如何实现异步io的. 其实本文是对[上一篇文][1]的实践和复习 主旨在于关注异步io的实现,所以会忽略掉代码中的一些异常处理.文字较多,凑合下吧 接下来只会贴出部分源码,帮助理解,希望有耐心的同学打开tornado源码,一起跟踪一遍吧. AsyncHTTPClient : AsyncHTTPClient 继承 Configurable ,从__new__重看出是单例模式. 根据 Configurable 的__new_

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

"重定向"简单介绍: "重定向"指的是HTTP重定向,是HTTP协议的一种机制.当client向server发送一个请求,要求获取一个资源时,在server接收到这个请求后发现请求的这个资源实际存放在另一个位置,于是server在返回的response中写入那个请求资源的正确的URL,并设置reponse的状态码为301(永久)或者 302(暂时),当client接受到这个response后就会根据新的URL重新发起请求.重定向有一个典型的特症,即,当一个请求被重定

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

Cookie和Session的理解: 具体Cookie的介绍,可以参考:HTTP Cookie详解 可以先查看之前的一篇文章:Tornado的Cookie过期问题 XSRF跨域请求伪造(Cross-Site-Request-Forgery): 简单的说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品).由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行.这利用了web中用户身份验证的一个漏洞:

tornado源码分析-Application

tornado.web包含web框架的大部分主要功能,Application是其中一个重要的类 Application类的作用是实现 URI 转发,将 Application 的实例传递给 httpserver ,当监听到请求时,把服务器传回来的请求进行转发,通过调用 __call__ ,处理请求. Application源码: class Application(httputil.HTTPServerConnectionDelegate): """A collection

(tornado源码分析_004)HTTP服务器处理解析出来的http数据

tornado中HTTP服务器是承上启下的作用,它通过tornado.http1connection.HTTP1ServerConnection与tornado.http1connection.HTTP1Connection从socket中读取并解析http消息 然后调用application处理解析出来的http消息,具体方法为:将application作为数据处理类传给上述两个读取数据的类 具体代码如下 #常见的torando启动方式 application = tornado.web.Ap

Tornado 的教材

作者:杨昆链接:https://www.zhihu.com/question/19707966/answer/12731684来源:知乎著作权归作者所有,转载请联系作者获得授权. 首先必看的是官网的文档, http://tornadoweb.org/ ,内容很少很快可以扫完,这里有中文翻译版, http://www.tornadoweb.cn/. tornado的新书 Introduction to tornado:Introduction to Tornado: Michael Dory, A