Python Day41 socketserver實現並發

來源:互聯網
上載者:User

標籤:線程   client   write   ftps   finish   print   get   服務端   ftpclient   

基於tcp的通訊端,關鍵就是兩個迴圈,一個連結迴圈,一個通訊迴圈

socketserver模組中分兩大類:server類(解決連結問題)和request類(解決通訊問題)

server類:

request類:

繼承關係:

尋找屬性的順序:ThreadingTCPServer->ThreadingMixIn->TCPServer->BaseServer

  1. 執行個體化得到ftpserver,先找類ThreadingTCPServer的__init__,在TCPServer中找到,進而執行server_bind,server_active
  2. 找ftpserver下的serve_forever,在BaseServer中找到,進而執行self._handle_request_noblock(),該方法同樣是在BaseServer中
  3. 執行self._handle_request_noblock()進而執行request, client_address = self.get_request()(就是TCPServer中的self.socket.accept()),然後執行self.process_request(request, client_address)
  4. 在ThreadingMixIn中找到process_request,開啟多線程應對並發,進而執行process_request_thread,執行self.finish_request(request, client_address)
  5. 上述四部分完成了連結迴圈,本部分開始進入處理通訊部分,在BaseServer中找到finish_request,觸發我們自己定義的類的執行個體化,去找__init__方法,而我們自己定義的類沒有該方法,則去它的父類也就是BaseRequestHandler中

源碼分析總結:

基於tcp的socketserver我們自己定義的類中的

  1.   self.server即通訊端對象
  2.   self.request即一個連結
  3.   self.client_address即用戶端地址

基於udp的socketserver我們自己定義的類中的

  1.   self.request是一個元組(第一個元素是用戶端發來的資料,第二部分是服務端的udp通訊端對象),如(b‘adsf‘, <socket.socket fd=200, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0, laddr=(‘127.0.0.1‘, 8080)>)
  2.   self.client_address即用戶端地址

 

import socketserverimport structimport jsonimport osclass FtpServer(socketserver.BaseRequestHandler):    coding=‘utf-8‘    server_dir=‘file_upload‘    max_packet_size=1024    BASE_DIR=os.path.dirname(os.path.abspath(__file__))    def handle(self):        print(self.request)        while True:            data=self.request.recv(4)            data_len=struct.unpack(‘i‘,data)[0]            head_json=self.request.recv(data_len).decode(self.coding)            head_dic=json.loads(head_json)            # print(head_dic)            cmd=head_dic[‘cmd‘]            if hasattr(self,cmd):                func=getattr(self,cmd)                func(head_dic)    def put(self,args):        file_path = os.path.normpath(os.path.join(            self.BASE_DIR,            self.server_dir,            args[‘filename‘]        ))        filesize = args[‘filesize‘]        recv_size = 0        print(‘----->‘, file_path)        with open(file_path, ‘wb‘) as f:            while recv_size < filesize:                recv_data = self.request.recv(self.max_packet_size)                f.write(recv_data)                recv_size += len(recv_data)                print(‘recvsize:%s filesize:%s‘ % (recv_size, filesize))ftpserver=socketserver.ThreadingTCPServer((‘127.0.0.1‘,8080),FtpServer)ftpserver.serve_forever()FtpServer
import socketimport structimport jsonimport osclass MYTCPClient:    address_family = socket.AF_INET    socket_type = socket.SOCK_STREAM    allow_reuse_address = False    max_packet_size = 8192    coding=‘utf-8‘    request_queue_size = 5    def __init__(self, server_address, connect=True):        self.server_address=server_address        self.socket = socket.socket(self.address_family,                                    self.socket_type)        if connect:            try:                self.client_connect()            except:                self.client_close()                raise    def client_connect(self):        self.socket.connect(self.server_address)    def client_close(self):        self.socket.close()    def run(self):        while True:            inp=input(">>: ").strip()            if not inp:continue            l=inp.split()            cmd=l[0]            if hasattr(self,cmd):                func=getattr(self,cmd)                func(l)    def put(self,args):        cmd=args[0]        filename=args[1]        if not os.path.isfile(filename):            print(‘file:%s is not exists‘ %filename)            return        else:            filesize=os.path.getsize(filename)        head_dic={‘cmd‘:cmd,‘filename‘:os.path.basename(filename),‘filesize‘:filesize}        print(head_dic)        head_json=json.dumps(head_dic)        head_json_bytes=bytes(head_json,encoding=self.coding)        head_struct=struct.pack(‘i‘,len(head_json_bytes))        self.socket.send(head_struct)        self.socket.send(head_json_bytes)        send_size=0        with open(filename,‘rb‘) as f:            for line in f:                self.socket.send(line)                send_size+=len(line)                print(send_size)            else:                print(‘upload successful‘)client=MYTCPClient((‘127.0.0.1‘,8080))client.run()FtpClient

 

Python Day41 socketserver實現並發

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.