tornado 有 tcpclient 和 tcpserver 兩個類,可用於實現 tcp 的客戶端和服務端。事實上,這兩個類都是對iostream的簡單包裝。
iostream 是 client 與 server 之間的 tcp 通道。被動等待建立 iostream 的一方是 server,主動找對方建立 iostream 的一方是 client。
在 iostream 建立之後,client 與 server 的操作再無分別,在任何時候都可以通過 iostream.write 向對方傳送內容,或者通過 iostream.read_xx(這是一組以 read_ 開頭的方法,有:read_bytes 讀取指定長度;read_until 讀取直到特定字元;read_until_regex 讀取直到特定正規表示式;read_until_close 讀取直到連線關閉)接收對方傳來的內容,或者以 iostream.close 關閉連線。
下邊是示例**中的 tcp_server.py
# -*- coding: utf-8 -*-解說:建立乙個繼承於 tcpserver 的類的例項,監聽埠,啟動伺服器,啟動訊息迴圈,伺服器開始執行。#!/usr/bin/env python
# @time : 2018/5/15 17:34
# @desc :
# @file : tcp_server.py
# @software: pycharm
from tornado import ioloop, gen, iostream
from tornado.tcpserver import tcpserver
class mytcpserver( tcpserver ):
@gen.coroutine
def handle_stream( self, stream, address ):
try:
while true:
msg = yield stream.read_bytes( 20, partial = true )
print msg, 'from', address
stream.write(str(msg))
yield stream.write( msg[::-1] )
if msg == 'over':
stream.close()
except iostream.streamclosederror:
pass
if __name__ == '__main__':
server = mytcpserver()
server.listen(8888)
server.start()
ioloop.ioloop.current().start()
這時,如果有 client 連線過來,tornado 會建立乙個 iostream,然後呼叫handle_stream 方法,呼叫時傳入的兩個引數是 iostream 和 client 的位址。我們示例的功能很簡單,每收到一段 20 字元以內的內容,將之反序回傳,如果收到 'over『,就斷開連線。
注意,斷開連線不用 yield 呼叫;無論是誰斷開連線,連線雙方都會各自觸發乙個 streamclosederror。
下邊是示例**中的 tcp_client.py
# -*- coding: utf-8 -*-解說:使用 tcpclient 比 tcpserver 更簡單,無須繼承,只要用 connect 方法連線到 server,就會返回 iostream 物件了。#!/usr/bin/env python
# @time : 2018/5/15 17:38
# @desc :
# @file : tcp_client.py
# @software: pycharm
from tornado import ioloop, gen, iostream
from tornado.tcpclient import tcpclient
@gen.coroutine
def trans():
stream = yield tcpclient().connect( '127.0.0.1',8888 )
try:
while true:
print tcpclient
data = raw_input("enter your input: ");
yield stream.write( str(data) )
back = yield stream.read_bytes( 20, partial = true )
msg = yield stream.read_bytes(20, partial=true)
print msg
print back
if data=='over':
break
except iostream.streamclosederror:
pass
if __name__ == '__main__':
ioloop.ioloop.current().run_sync( trans )
在本例中,我們向 server 傳送一些字串,它都會反序發回來。最後發個 'over',讓 server 斷開連線。
當然也可以由 client 斷開;值得注意,這段**與之前的幾個例子有個根本的區別,之前都是伺服器,被動等待行為發生,而這段**是一執行就主動發起行為(連線),因此它的執行方式不同於以往,需要我們主動通過 ioloop 的 run_sync 來呼叫。
以往那些例項中的非同步處理方法實際是由 tornado 呼叫的。在 run_sync 裡,tornado 會先啟動訊息迴圈,執行目標函式,之後再結束訊息迴圈。
在第乙個終端視窗執行 tcp_server.py,在第二個終端視窗執行 tcp_client.py,即可看到它們之間的互動和斷開的過程。
注意:最好輸入英文本串測試。
Tornado非同步學習
why asynchronous tornado是乙個非同步web framework,說是非同步,是因為tornado server與client的網路互動是非同步的,底層基於io event loop。但是如果client請求server處理的handler裡面有乙個阻塞的耗時操作,那麼整體的s...
Tornado非同步模式
先介紹下背景 由於工作需要,前段時間又寫了一段爬蟲去獲取和更新一些資料。之前爬蟲主要用scrapy框架批量爬取一些頁面資料,或者用gevent呼叫目標站點的介面。偶然看到了tornado,聽說這個框架很強大,所以打算這次爬蟲用tornado試試。不足之處,歡迎指正。總的來說,tornado是pyth...
tornado中非同步request使用
使用httprequest太無腦了,太莽了,當希望使用非同步request時,首先引入asynchttprequest from tornado.httpclient import asynchttpclient將介面中的方法新增上tornado的協程符 coroutine根據request的方式 ...