First, socketserver implementation of concurrent programming
such as the Socketserver module is based on multi-threaded implementation of concurrent programming classes and multi-process-based implementation of concurrent programming classes, it is actually the internal implementation of the mechanism is to learn to implement multi-threaded, multi-process process encapsulation, according to a specific process can be used, which is commonly used in the TCP protocol communication , multi-Threading module is threadingtcpserver, multi-process module is forkingtcpserver, need to explain is socketserver module in the multi-process can not be implemented in Windows system, So here for the time being mainly introduce the method of multithreading implementation based on TCP protocol.
FTP Multi-User Communication example:
#Service SideImportSocketserverImportstructImportJSONImportOSclassFtpserver (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 ()
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< /c7>=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 ()
In the above example, implementing concurrent multithreading is a service-side, the main implementation of the following multi-user communication example:
Service side:
ImportSocketserverclassMyserver (Socketserver. Baserequesthandler):#You must create a class and inherit the Socketserver. Baserequesthandler class defHandle (self):#This method must have, and the method name can not be changed, it is the method that the instance automatically executes after creating the connection whileTrue:data=SELF.REQUEST.RECV (1024)#self.request equivalent to Conn if notData BreakSelf.request.send (Data.upper ())if __name__=='__main__': Server=socketserver. Threadingtcpserver (('127.0.0.1', 8090), Myserver)#instantiate an objectServer.serve_forever ()#looping to establish a connection
Client:
import socketclient =socket.socket (socket.af_inet,socket. Sock_stream) Client.connect (( " 127.0.0.1 ", 8090 While true:msg =input ( " >>> " ). Strip ( if not msg: continue Client.send (Msg.encode ()) Data =CLIENT.RECV (1024 ) print (Data.decode ())
Python Learning _day41_socketserver Module