python3socket非阻塞_python 如何连续读取一个由服务器发来的非阻塞请求?

3

2014-11-22 21:37:03 +08:00

如果是tornado4, 可以用chunked transfer enoding传送,那么客户端支持chunk编码就可以做数据接收了。http://en.wikipedia.org/wiki/Chunked_transfer_encoding。

tornado3不支持chunk:

import tornado.ioloop

import tornado.iostream

import socket

```python

class WebRequest(object):

LINE_END = b'\r\n'

def __init__(self, host, port=80, callback=None):

self.host = host

self.port =port

self.headers = {}

self.data = ''

self.callback = callback

self.transfer = 'stream'

self.http_ver_with_status = ''

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)

self.stream = tornado.iostream.IOStream(s)

self.stream.connect((self.host, self.port), self.send_request)

def send_request(self):

self.stream.write(b"GET / HTTP/1.0\r\nHost: %s\r\n\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36\r\n" %self.host)

self.stream.read_until(self.LINE_END*2, self.on_headers)

def on_headers(self, data):

for line in data.split(self.LINE_END):

parts = line.split(b":", 1)

if len(parts) == 2:

self.headers[parts[0].strip()] = parts[1].strip()

else:

self.http_ver_with_status = line

if 'Content-Length' in self.headers:

if int(self.headers[b"Content-Length"]) > 0:

print self.headers

print 'content_length: ', self.headers[b"Content-Length"]

self.transfer = 'content_length'

self.stream.read_bytes(int(self.headers[b"Content-Length"]), self.on_body)

else:

self.callback(self)

self.stream.close()

elif self.headers.get(b'Transfer-Encoding') == 'chunked':

print 'chunk'

self.transfer = 'chunked'

self.on_chunk()

else:

self.transfer = 'stream'

callback = lambda data: self.on_stream(data, True)

streaming_callback = lambda data: self.on_stream(data, False)

self.stream.read_until_close(callback, streaming_callback)

def on_body(self, data):

self.data += data

self.callback(self)

self.stream.close()

def on_chunk(self):

self.stream.read_until_regex(self.LINE_END, self.on_chunk_header)

def on_chunk_header(self, data):

length = int(data)

if length > 0:

self.stream.read_bytes(length+len(self.LINE_END), self.on_chunk_data)

else:

self.stream.read_bytes(length+len(self.LINE_END), self.on_chunk_end)

def on_chunk_end(self, data):

self.callback(self)

self.stream.close()

def on_chunk_data(self, data):

print data

self.data += data

self.on_chunk()

def on_stream(self, data, finish=False):

# do some thing

if finish:

self.data += data

self.callback(self)

self.stream.close()

else:

self.data += data

def callback(req):

print req.http_ver_with_status

print "Transfer :" , req.transfer

print "Headers: ", req.headers

print "Data: ", req.data

req = WebRequest('cn.bing.com', 80, on_bing)

def on_bing(req):

print req.http_ver_with_status

print "Transfer :" , req.transfer

print "Headers: ", req.headers

print "Data: ", req.data

tornado.ioloop.IOLoop.instance().stop()

if __name__ == '__main__':

req = WebRequest('www.baidu.com', 80, callback)

tornado.ioloop.IOLoop.instance().start()

```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值