該模塊提供了異步socket服務客戶端和服務器的基礎架構。html
只有兩種方法讓程序在單個處理器上的同時作超過一件的事情。 多線程編程是最簡單,最廣泛的方式,但還有另外一種很是不一樣的技術,可讓你具備多線程幾乎全部的優勢,實際上並無使用多線程。程序的瓶頸主要在於I/O時是比較可行的。若是你的程序的瓶頸在處理器,確實須要多線程,不過網絡服務器的瓶頸大多在I/O。python
若是您的操做系統支持I/O庫的select()系統調用(通常都支持) ,那麼你可使用它同時處理多個通訊信道,作其餘的工做的同時讓I/O在後臺執行,這比多線程更容易理解。編程
asyncore和asynchat的基本思路是建立一個或多個網絡通道,即asyncore.dispatcher和asynchat.async_chat的實例。而後添加到全局映射,若是你沒有建立本身的映射,能夠直接使用loop()函數。loop()激活全部通道服務,執行直到最後一個通道關閉。服務器
asyncore.loop([timeout[, use_poll[, map[, count]]]])網絡
進入輪詢循環直到全部打開的通道已被關閉或計數經過。全部的參數都是可選的。 count參數默認爲None,只有當全部通道都被關閉時循環纔會終止。 timeout參數設置爲select()或poll()調用設置超時,以秒爲單位,默認爲30秒。use_poll參數,若是爲true ,則表示 poll()優先於select(),默認值爲False。map是包含監控的channel的字典。channel關閉時會從map中刪除。不指定map時會使用全局map。Channel(asyncore.dispatcher , asynchat.async_chat和其子類的實例)能夠自由地混合在map上)。多線程
class asyncore.dispatcher: dispatcher底層socket的輕便包裝。它有一些事件處理供異步循環調用。不然,它能夠被視爲一個正常的非阻塞socket對象。底層事件的觸發或者鏈接狀態改變通知異步循環發生了高層事件,高層事件有:架構
handle_connect():Implied by the first read or write event。app
handle_close():Implied by a read event with no data available。異步
handle_accept():Implied by a read event on a listening socket。socket
asyncore.dispatcher的新方法:在異步處理,每一個映射通道的readable()和writable()方法用於肯定通道的socket是否應該被添加到select()或poll()通道的頻道列表中以讀寫事件。所以通道事件比基本socket 事件要多。在子類中重寫的方法以下:
handle_read():當異步循環檢測到通道的read()將成功時調用。
handle_write():當異步循環檢測到通道的write()將成功時調用。須要緩衝以提升性能。
def handle_write(self): sent = self.send(self.buffer) self.buffer = self.buffer[sent:]
handle_expt():當有socket鏈接有帶外數據【 out of band (OOB)】時調用。這幾乎不會發生,由於OOB的支持很好且不多使用。
handle_connect():當活動socket實際建立鏈接時調用。可能發送「welcome」 banner,或與遠程端點啓動協議協商。
handle_close():當關閉socket時調用。
handle_error():當異常引起又沒有其餘處理時調用。默認版本print壓縮的traceback。
handle_accept():監聽通道(被動開啓) ,當本端經過connect()能夠和遠端創建鏈接時在監聽通道(被動開啓)上調用。
readable():每次異步循環時調用,以肯定通道的socket是否應該被添加到產生讀事件列表。默認的方法只返回True,表示在默認狀況下,全部通道將擁有讀取事件。
writable():每次異步循環時調用,以肯定通道的socket是否應該被添加到產生寫事件列表。默認的方法只返回True,表示在默認狀況下,全部通道將擁有寫事件。
下面方法和socket相同,有些有所擴充:
create_socket(family, type):參見socket文檔。
connect(address):參見socket文檔。
send(data):發送數據到遠端socket。
recv(buffer_size):從遠端socket最多接收buffer_size字節的數據。空字符串意味着該信道已被遠端關閉。
listen(backlog):監聽的鏈接數,默認和最小值都爲1,最大值根據系統肯定,通常是5。
bind(address):綁定socket到address。socket必須未綁定。地址的格式取決於地址族 ,參見socket文檔。調用set_reuse_addr()方法能夠把socket設置爲可重用的(參見設置SO_REUSEADDR選項)。
accept():接受鏈接。socket必須綁定到地址和監聽鏈接。返回值能夠是None 或一對(conn, address),其中conn是新的可用來在鏈接上發送和接收數據socket對象,address 是綁定到鏈接上遠端套接字的地址。None意味着鏈接並無發生,在這種狀況下,服務器應該忽略並繼續偵聽其餘鏈接。
close():關閉套接字。 Socket對象上的全部將來的操做將失敗。遠端將接收沒有更多的數據(排隊數據清空以後) 。socket也會被垃圾收集自動關閉。
asyncore.dispatcher_with_send:dispatcher的子類,增長了簡單的緩衝輸出,對於簡單的客戶端有用。詳細資料參考:asynchat.async_chat。
class asyncore.file_dispatcher:封裝了文件描述符或文件對象及映射參數(可選)供poll()和loop()函數使用的文件分發器。它提供了文件對象或其餘具有fileno()方法的對象,調用fileno()並傳遞到file_wrapper構造函數。可用於UNIX。
class asyncore.file_wrapper:接收整數文件描述符並調用os.dup()複製句柄,這樣原句柄能夠關閉,而文件包裝器不受影響。該類封裝了大量方法以模擬socket給file_dispatcher類使用。可用於UNIX。
import asyncore, socketclass HTTPClient(asyncore.dispatcher): def __init__(self, host, path): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.connect( (host, 80) ) self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path def handle_connect(self): pass def handle_close(self): self.close() def handle_read(self): print self.recv(8192) def writable(self): return (len(self.buffer) > 0) def handle_write(self): sent = self.send(self.buffer) self.buffer = self.buffer[sent:]client = HTTPClient('192.168.4.13', '/env.htm')asyncore.loop()
上面的HTTPClient鏈接外面的服務器通常都會報不存在,鏈接本地的就好。
import asyncoreimport socketclass EchoHandler(asyncore.dispatcher_with_send): def handle_read(self): data = self.recv(8192) if data: self.send(data)class EchoServer(asyncore.dispatcher): def __init__(self, host, port): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.set_reuse_addr() self.bind((host, port)) self.listen(5) def handle_accept(self): pair = self.accept() if pair is not None: sock, addr = pair print 'Incoming connection from %s' % repr(addr) handler = EchoHandler(sock)server = EchoServer('localhost', 8080)asyncore.loop()
《The Python Standard Library by Example 2011》
本站地址:python自動化測試http://automationtesting.sinaapp.com python開發自動化測試羣113938272和開發測試羣6089740 微博 http://weibo.com/cizhenshi