Tornado 非同步socketTCP通訊

2022-08-31 00:57:09 字數 3251 閱讀 4199

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 -*-

#!/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()

解說:建立乙個繼承於 tcpserver 的類的例項,監聽埠,啟動伺服器,啟動訊息迴圈,伺服器開始執行。

這時,如果有 client 連線過來,tornado 會建立乙個 iostream,然後呼叫handle_stream 方法,呼叫時傳入的兩個引數是 iostream 和 client 的位址。我們示例的功能很簡單,每收到一段 20 字元以內的內容,將之反序回傳,如果收到 'over『,就斷開連線。

注意,斷開連線不用 yield 呼叫;無論是誰斷開連線,連線雙方都會各自觸發乙個 streamclosederror。

下邊是示例**中的 tcp_client.py

# -*- coding: utf-8 -*-

#!/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 )

解說:使用 tcpclient 比 tcpserver 更簡單,無須繼承,只要用 connect 方法連線到 server,就會返回 iostream 物件了。

在本例中,我們向 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的方式 ...