tornado源码分析-iostream

1.iostream.py作用

用来异步读写文件,socket通信

2.使用示例

import tornado.ioloop
import tornado.iostream
import socket def send_request():
stream.write(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')
stream.read_until(b"\r\n\r\n", on_headers) def on_headers(data):
headers = {}
for line in data.split(b"\r\n"):
parts = line.split(b":")
if len(parts) == 2:
headers[parts[0]] = parts[1]
stream.read_bytes(int(headers[b"Content-Length"]), on_body) def on_body(data):
print(data)
with open('sina.html', 'wb') as f:
f.write(data)
stream.close()
tornado.ioloop.IOLoop.current().stop() if __name__ == '__main__':
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
stream = tornado.iostream.IOStream(client_socket)
stream.connect(("www.sina.com.cn", 80), send_request)
tornado.ioloop.IOLoop.current().start()

与传统socket通信的区别是,iostream对socket进行了包装,可以进行异步的读写。

3.iostream主要功能

class IOStream(BaseIOStream):
def read_until(self, delimiter, callback):
future = self._set_read_callback(callback)
self._read_delimiter = delimiter
self._read_max_bytes = max_bytes
try:
self._try_inline_read()
except:
...
def read_bytes(self, num_bytes, callback, streaming_callback=None)
...
def read_until_regex(self, regex, callback):
...
def read_until_close(self, callback, streaming_callback=None):
...
def write(self, data, callback=None):
... def _handle_events(self, fd, events):
...
def _add_io_state(self, state):
...
if self._state is None:
self._state = ioloop.IOLoop.ERROR | state
with stack_context.NullContext():
self.io_loop.add_handler(
self.fileno(), self._handle_events, self._state)
elif not self._state & state:
self._state = self._state | state
self.io_loop.update_handler(self.fileno(), self._state)
def connect(self, address, callback=None, server_hostname=None):
... def _try_inline_read(self):
# See if we've already got the data from a previous read
self._run_streaming_callback()
pos = self._find_read_pos()
if pos is not None:
self._read_from_buffer(pos)
return
self._check_closed()
try:
pos = self._read_to_buffer_loop()
except Exception:
...
if pos is not None:
self._read_from_buffer(pos)
return
if self.closed():
self._maybe_run_close_callback()
else:
self._add_io_state(ioloop.IOLoop.READ) def _read_from_buffer(self, pos):
self._read_bytes = self._read_delimiter = self._read_regex = None
self._read_partial = False
self._run_read_callback(pos, False) def _run_read_callback(self, size, streaming):
if streaming:
callback = self._streaming_callback
else:
callback = self._read_callback
self._read_callback = self._streaming_callback = None
if self._read_future is not None:
assert callback is None
future = self._read_future
self._read_future = None
future.set_result(self._consume(size))
if callback is not None:
assert (self._read_future is None) or streaming
self._run_callback(callback, self._consume(size))
else:
self._maybe_add_error_listener() def _consume(self, loc):
...

read_until:读到delimiter结束

read_bytes:读取num_bytes个字符后结束

read_until_regex:读取到正则匹配到后结束

read_until_close:读取到scoket关闭后结束

读流程:

self._run_streaming_callback()

字节流回调,待研究

future = self._set_read_callback(callback)

注册读完成回调事件

pos = self._find_read_pos()

读取位置

self._read_from_buffer(pos)

从缓存读取

pos = self._read_to_buffer_loop()

socket等待接收数据,放入缓存

self._read_from_buffer(pos)

从缓存读取

self._consume(size)

读缓冲器size个字节,从缓冲区删除并返回这些数据

_maybe_add_error_listener

没有可读数据,开启监听read事件,当read事件发生时再调用handle_read处理

_pending_callbacks

控制信号量,待研究

write:首先将data按数据块大小WRITE_BUFFER_CHUNK_SIZE分块写入write_buffer,

然后调用handle_write向socket发送数据

connect:建立非阻塞socket连接,注册ioloop可写事件

_add_io_state:为ioloop注册或更新READ,WRITE,ERROR事件,ioloop异步执行读socket,写socket操作等

handle_read:从socket读到缓冲区

handle_write:由缓冲区向socket写

tornado源码分析-iostream的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. tornado源码分析系列一

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

  7. tornado源码分析

    初识tornado 首先从经典的helloword案例入手 import tornado.ioloop import tornado.web class MainHandler(tornado.web ...

  8. tornado源码分析-多进程

    1.源码文件 process.py 2.fork子进程 def fork_processes(num_processes, max_restarts=100): ... def start_child ...

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

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

随机推荐

  1. java服务端微信小程序支付

    发布时间:2018-10-05   技术:springboot+maven   概述 java微信小程序demo支付只需配置支付一下参数即可运行 详细 代码下载:http://www.demodash ...

  2. iOS 瀑布流之栅格布局

    代码地址如下:http://www.demodashi.com/demo/14760.html 一 .效果预览 二.确定需求 由下面的需求示意图可知模块的最小单位是正方形,边长是屏幕宽除去边距间隔后的 ...

  3. Oracle用分区表分区交换做历史数据迁移

    一. 说明: OLTP库中有些表数据量大,且每月有持续的大量数据添加.因为历史数据在此库中不再做訪问,而是在另1个OLAP库中做分析.所以会对历史数据迁移至OLAP库中.对这样的历史数据迁移的操作.较 ...

  4. Redis五大数据类型常用命令脑图

  5. node下使用jquery

    node使用jquery的两种方式 在node下,使用jquery有两种方法: 使用jsdom模拟一个window对象 使用cheerio,cheerio只实现了jquery的dom部分功能,相当于j ...

  6. 如何设置页面自动刷新第一篇?? servlet setHeader("refresh","2")

    import java.io.IOException; import java.util.Random; import javax.servlet.ServletException; import j ...

  7. 构建高性能web之路------mysql读写分离实战(转)

    一个完整的mysql读写分离环境包括以下几个部分: 应用程序client database proxy database集群 在本次实战中,应用程序client基于c3p0连接后端的database ...

  8. label 赋值 , 隐藏 , 显示

    <label name='by_stages_number' id='by_stages_number'></label> document.getElementById(&q ...

  9. Android之内存泄露、内存溢出、内存抖动分析

      内存   JAVA是在JVM所虚拟出的内存环境中运行的,内存分为三个区:堆.栈和方法区.栈(stack):是简单的数据结构,程序运行时系统自动分配,使用完毕后自动释放.优点:速度快.堆(heap) ...

  10. 如何调试makefile变量

    六.七年前写过一篇<跟我一起写Makefile>,直到今天,还有一些朋友问我一些Makefile的问题,老实说,我有一段时间没有用Makefile了,生疏了.回顾,这几年来大家问题我的问题 ...