TCP-based sockets, the key is two loops, a link loop, a communication loop
There are two main classes in the Socketserver module: the server class (solve the link problem) and the request class (to solve the communication problem)
Server class:
Request class:
Inheritance Relationship:
Order of Lookup properties: Threadingtcpserver->threadingmixin->tcpserver->baseserver
- Instantiate get Ftpserver, first find class Threadingtcpserver __init__, found in TCPServer, and then execute server_bind,server_active
- Find Ftpserver under the Serve_forever, found in Baseserver, and then execute Self._handle_request_noblock (), the method is also in the Baseserver
- Executes Self._handle_request_noblock () and then executes the request, client_address = Self.get_request () (which is self.socket.accept in TCPServer ( ), and then execute self.process_request (Request, client_address)
- Find Process_request in ThreadingMixIn, turn on multithreading to handle concurrency, and execute Process_request_thread, execute self.finish_request (request, Client_ Address
- The above four parts completed the link loop, this section began to enter the processing of the communication section, found in the Baseserver finish_request, triggering our own definition of the class instantiation, to find __init__ method, and our own definition of the class does not have the method, Then go to its parent class, which is Baserequesthandler.
SOURCE Analysis Summary:
TCP-based socketserver in our own defined class.
- Self.server is a Socket object
- Self.request is a link
- Self.client_address is the client address
UDP-based socketserver in our own defined class.
- Self.request is a tuple (the first element is the data sent by the client, the second part is the UDP socket object on the server), such as (b ' adsf ', <socket.socket fd=200, family=addressfamily.af_ INET, Type=socketkind.sock_dgram, proto=0, laddr= (' 127.0.0.1 ', 8080) >)
- Self.client_address is the client address
ImportSocketserverImportstructImportJSONImportOSclassFtpserver (socketserver. Baserequesthandler): Coding='Utf-8'Server_dir='File_upload'max_packet_size=1024Base_dir=os.path.dirname (Os.path.abspath (__file__)) defhandle (self):Print(self.request) whileTrue: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'] ifhasattr (self,cmd): Func=getattr (Self,cmd) func (head_dic)defput (Self,args): File_path=Os.path.normpath (Os.path.join (self). Base_dir, Self.server_dir, args['filename'])) FileSize= args['filesize'] Recv_size=0Print('----->', File_path) with open (File_path,'WB') as F: whileRecv_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
ImportSocketImportstructImportJSONImportOSclassmytcpclient:address_family=socket.af_inet Socket_type=socket. Sock_stream allow_reuse_address=False max_packet_size= 8192Coding='Utf-8'request_queue_size= 5def __init__(Self, server_address, connect=True): self.server_address=server_address Self.socket=Socket.socket (self.address_family, Self.socket_type)ifConnect:Try: Self.client_connect ()except: Self.client_close ()Raise defClient_connect (self): Self.socket.connect (self.server_address)defClient_close (self): Self.socket.close ()defRun (self): whileTRUE:INP=input (">>:"). Strip ()if notInp:ContinueL=inp.split () cmd=L[0]ifhasattr (self,cmd): Func=getattr (Self,cmd) func (L)defput (Self,args): cmd=args[0] FileName=args[1] if notos.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< /c1>=0 with open (filename,'RB') as F: forLineinchF: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 Implementation concurrency