loadlj / blog

19 stars 6 forks source link

IOStream分析 #3

Open loadlj opened 8 years ago

loadlj commented 8 years ago

IOStream

socket的非阻塞IO的读写操作封装

函数说明

__init__

初始化的时候将_self._handle_events_作为handler添加到IOLoop中,等待读事件

read_until

接收一个_delimiter_作为分隔符,当读取到_delimiter_的时候,调用callback。读取完后更新IOLoop事件,等待读事件。

read_bytes

接收一个_num_bytes_作为分隔符,当读取字节大于_num_bytes_的时候,调用callback。读取完后更新IOLoop事件,等待读事件。

write

将需要写的字符添加到_self._writebuffer, 调用__add_iostate,更新IOLoop事件,等待写事件。

_handle_events

当fd状态发生改变的时候,对fd和相应事件进行处理。有读事件的时候,调用handleread, 有写事件的时候调用handlewrite。当_self._write_buffer_不为空时更新写事件,当_self._read_delimiter_或者_self._read_bytes_更新写事件。

_handle_read

将读取到的内容加载到_self._read_buffer_中,回调_self._readbytes,清空_self._readbuffer

_handle_write

将_self._write_buffer_发送,回调_self._writecallback

通过test case 进行流程分析

import socket
from tornado import ioloop, iostream

s = socket.socket()
s.connect(("baidu.com", 80))
stream = iostream.IOStream(s)

def on_headers(data):
    headers = {}
    for line in data.split("\r\n"):
        parts = line.split(":")
        if len(parts) == 2:
            headers[parts[0].strip()] = parts[1].strip()
    stream.read_bytes(int(headers["Content-Length"]), on_body)

def on_body(data):
    print data
    stream.close()
    ioloop.IOLoop.instance().stop()

stream.write("GET / HTTP/1.0\r\n\r\n")
stream.read_until("\r\n\r\n", on_headers)
ioloop.IOLoop.instance().start()

流程图