利用python-twisted庫實現一個檔案收發服務

來源:互聯網
上載者:User

標籤:

最近在學習python-twisted庫,之前做非同步並發編程一直都是使用c++,比如linux下的epoll機制,windows的IOCP機制,到後來經常使用的Boost::Asio庫,比較搞的是c++上的非同步經驗反而有點阻礙我開始學習twisted庫,原因如下:

不管是epoll還是IOCP,都是當讀操作或者寫操作可執行時(IOCP則是完成時)會得到一個通知,然後可以執行自己的下一步代碼。這種情景下如果你是做較大資料的收發的話,就可以在得到通知時進行必要的處理後繼續發送或者接受下一個資料區塊,但是twisted的庫則不是這樣設計的,以twisted.protocols.basic.LineReceiver為例,當非同步收到資料後,該類的lineReceived函數或者rawDataReceived(取決於當前的模式)會被觸發,但是它並不包含非同步寫函數,也就是說你無法這樣操作:

1、調用非同步發送函數發送資料

2、資料發送完成時觸發一個回呼函數

3、在該回呼函數中你決定後續的操作,比如繼續發送下一塊資料

那麼twisted的解決方案是什嗎?答案是producer/consumer ,producer負責源源不斷的產生資料(如不斷從file中讀取資料),consumer負責處理資料(通過socket發送出去),當consumer在發送時緩衝滿了它會通知producer暫停提供資料,當緩衝清空後繼續通知producer產生資料(這就類似我們上面提到的,當非同步發送完成時調用一個回呼函數),這個的過程不需要我們在代碼中顯示的控制。由於檔案發送應用的普遍性,twisted提供了一個檔案發送類FileSender,好啦,描述性的內容就到這裡,後續關於producer/consumer我會進一步介紹,下面直接上代碼

 

from twisted.internet.protocol import Protocol,Factoryfrom twisted.protocols.basic import LineReceiverfrom twisted.protocols.basic import FileSenderfrom twisted.internet.defer import Deferredimport pickle,structimport multiprocessing.poolimport os,jsonclass TransferFileProtocol(LineReceiver):    port_ = 0    def __init__(self):        self.handle_f_ = None        #--------------------------        self.instruction_ = None        self.command_ = None        self.size_remain_ = 0        #self.setRawMode()    def _monitor(self,data):        self.size_remain_-=len(data)        return data    def cbTransferOver(self, lastSent):        print(‘download over!‘)        self.transport.loseConnection()    def connectionMade(self):        print(‘Got Connection from ‘,self.transport.client)        print ‘work on port:%d‘ % (self.port_,)    def connectionLost(self,reason):        print(self.transport.client, ‘ disconnected!‘)        if self.handle_f_ != None:            self.handle_f_.close()        if self.size_remain_ != 0:            print ‘transfer file fail!‘#            if self.command_ == ‘put‘:#                os.    def lineReceived(self, line):        self.instruction_ = json.loads(line)        self.command_ = self.instruction_[‘command‘]        name_file = self.instruction_[‘name_file‘]        if self.command_ == ‘put‘:            self.size_remain_ = self.instruction_[‘size_file‘]            try:                self.handle_f_ = open(‘files/%s‘ % (name_file,),‘wb‘)            except:                print ‘open %s fail!‘ % (name_file,)                self.handle_f_ = None#                self.transfer.loseConnection()            else:                self.setRawMode()        elif ‘get‘ == self.command_:            self.size_remain_ = 0            if os.path.exists(‘files/%s‘ % (name_file,)):                self.size_remain_ = os.stat(‘files/%s‘ % (name_file,)).st_size            instruction = dict(size_file=self.size_remain_)            if self.size_remain_>0:                try:                    self.handle_f_ = open(‘files/%s‘ % (name_file,),‘rb‘)                except:                    self.size_remain_ = 0                    self.handle_f_ = None                else:                    self.setRawMode()            self.transport.write(json.dumps(instruction)+‘\r\n‘)            if self.size_remain_>0:                sender = FileSender()                sender.CHUNCK_SIZE = 2**16                d = sender.beginFileTransfer(self.handle_f_,self.transport,self._monitor)                d.addCallback(self.cbTransferOver)    def rawDataReceived(self, data):        print ‘length of data:%d‘ % (len(data),)        if ‘put‘ == self.command_ and self.handle_f_ != None:            self.handle_f_.write(data)            self.size_remain_ -= len(data)def recv_func(port):    from twisted.internet import epollreactor    epollreactor.install()    from twisted.internet import reactor    TransferFileProtocol.port_ = port    factory = Factory()    factory.protocol = TransferFileProtocol    reactor.listenTCP(port,factory)    reactor.run()if __name__ ==‘__main__‘:    ports = [6200,6202,6204,6206]    pool = multiprocessing.pool.Pool(len(ports))    pool.map(recv_func,ports)#    recv_func(6200)

 

利用python-twisted庫實現一個檔案收發服務

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.