Review the procedure for socket programming:
Server side: 1 Declares the socket instance servers = Socket.socket () #括号里不写 The default address cluster uses af_inet that is IPv4 default type is sock. Sock_stream that is TCP/IP protocol 2 bind the address and Port server.bind ((' localhost ', 9999)) #ip地址和端口 tuple form, the port is an integer form 3 start listening Server.listen () 4 into the block Status, waiting for the connection to enter ######## from here, you can join the loop and loop the different connections so that you can accept the connection of the different clients ##### #while True: # Get the client IP address and port open a connection instance ############## from here Loop, so that you can loop to receive client data, but only to receive this one client ############ #客户端一断开, Conn received is all empty data, so enter a dead loop, so need an if judgment #while true:5 data = CONN.RECV (1024x768) #接收最大数据量, the official recommended maximum of 8192 write the whole data # Add the If judgment # if not data:# breakprint (data) 6 can send back data conn.send (Data.upper () ) #可以发送任何数据, here to turn the received into uppercase 7 Server.close () client: 1 Declaration Socket instance: client= Socket.socket () 2 connection server: Client.connect (' server_ip ', 9999)) #连接服务端的ip及端口 tuple form, the port is an integer form 3 data client.send #发送数据, any data # 4 receives the data returned by the server # Recv_data = CLIENT.RECV (1024)
Dynamic Import Module:
1 Practice: 2 1 lib AA 3 def Test (): 4 print ("hehe") 5 class C (object): 6 name = "Yang" 7 def __init__ (self): 8
self.name = ' Shenyang '
9 lib test10 import importlib11 dd = importlib.import_module (' Lib.aa ') dd.test () print (DD. C (). Name)
Run:
Assertion:Correct judgment of the type of judgment
Judgment error
Same as if, but more concise, a sentence is OK
Continue with socket programming:
Although the client write is 1024 but not necessarily receive 1024 to receive a maximum of 1024 even if the server returns 100 bytes also received by the client received data, how much to the service side first send a number of data to send, the client received, began to receive data, until the specified size of the data, no longer received
Practice: Service-side
1 #!/usr/bin/env python3 2 # author:shen Yang 3 Import socket,os 4 ip_address = ' 192.168.16.10 ' 5 port = 8888 6 bind_addr ESS = (ip_address,port) 7 server = Socket.socket () 8 Server.bind (bind_address) 9 Server.listen () while True:11 Conn, addr = Server.accept () while true:13 data = CONN.RECV (1024x768). Decode () if not data:15 print ("Lost connection") break17 Print ("This is from", addr,data) cmd_res = Os.popen (data). Read () conn.send (str (LEN (cmd_ Res.encode (' Utf-8 '))). Encode (' Utf-8 ')) conn.send (Cmd_res.encode (' Utf-8 ')) Server.close ()
Client
1 #!/usr/bin/env python3 2 # author:shen Yang 3 Import socket 4 ip_address = ' 192.168.16.10 ' 5 # ip_address = ' 192.168.81 .133 ' 6 port = 8888 7 conn_address = (ip_address,port) 8 client = Socket.socket () 9 client.connect (conn_address) Ten while T rue:11 cmd = input (":>"). Encode (' Utf-8 ') if len (cmd) = = 0:13 continue14 client.send (CMD) 15 cmd_size = Int (CLIENT.RECV (1024x768). Decode ()) print (cmd_size) recov_size = 018 Recov_data = B ' 19 While Recov_size < cmd_size:20 data = CLIENT.RECV (1024x768) #print (data), recov_size + = len (data ) #print (recov_size) recov_data + = data25 else:26 print ("Finished, size", recov_size) Print (Recov_data.decode ()) Client.close ()
The above code in Linux send will appear sticky packet client received is two data
The ultimate solution: Add the receive process to the server:
Client Plus Send process:
Practice: Ssh_server:
#!/usr/bin/env python3import socket,osip_address = ' 192.168.81.133 ' port = 8888bind_address = (ip_address,port) Server = Socket.socket () server.bind (bind_address) Server.listen () while true: conn,addr = server.accept () while true: data = CONN.RECV (1024x768). Decode () if not data: print ("Lost connection") break print ("This is from", Addr,data) Cmd_res = Os.popen (data). Read () conn.send (str (LEN (cmd_res.encode (' Utf-8 '))). Encode (' Utf-8 ')) ack = CONN.RECV (1024x768). Decode () print (ACK) conn.send (Cmd_res.encode (' Utf-8 ')) Server.close ()
Ssh_client
1 #!/usr/bin/env python3 2 Import socket 3 IP_Address = ' 192.168.81.133 ' 4 port = 8888 5 conn_address = (ip_address,port) 6 client = Socket.socket () 7 client.connect (conn_address) 8 while true:9 cmd = input (":>"). Encode (' Utf-8 ' ) If Len (cmd) = = 0:11 continue12 client.send (cmd) cmd_size = Int (CLIENT.RECV (1024x768). Decode ()) Print (cmd_size) client.send ("Received size". Encode (' Utf-8 ')) recov_size = 017 Recov_data = B " Recov_size < cmd_size:19 data = CLIENT.RECV (1024x768) #print (data) recov_size + = len (data) #print (recov_size) recov_data + = Data24 else:25 print ("Finished, size", recov_size)- print (recov_ Data.decode ()) Client.close ()
Upload file:Server-side logic:
Use Os.stat to get file details, send to Client
Another way to solve a sticky bag:
Only data of a specified size can never be glued to a packet
Practice: ftp_server.py
1 #!/usr/bin/env python3 2 import socket,os,hashlib 3 ip_address = ' 192.168.81.133 ' 4 port = 8888 5 Bind_address = ( Ip_address,port) 6 server = Socket.socket () 7 server.bind (bind_address) 8 Server.listen () 9 while true:10 conn,addr = Server.accept () One while true:12 print ("Waiting for new link") data = CONN.RECV (1024x768) if not data:15 Print ("Lost connection") Break17 print ("This is from", addr,data) Cmd,file_name = Data.decode (). Split () If Os.path.isfile (file_name): M = Hashlib.md5 () F = open (file_name, ' RB ') fi Le_size = Os.stat (file_name). St_size23 conn.send (str (file_size). Encode ()) ACK = CONN.RECV (1024x768). Deco De () Print ("Confirm:", ack)-f:27 m.update (line) + print ("Sending ..." ) Conn.send (line) F.close () to Conn.send (M.hexdigest (). Encode ()) print ("Send Complete" ) Server.close ()
ftp_client.py
1 #!/usr/bin/env python3 2 import socket,hashlib 3 ip_address = ' 192.168.81.133 ' 4 port = 8888 5 Conn_address = (ip_addre Ss,port) 6 client = Socket.socket () 7 client.connect (conn_address) 8 while true:9 cmd = input ("Input your Cmd:>") . Strip () If Len (cmd) = = 0:11 Continue12 if Cmd.startswith ("get"): Client.send (Cmd.encode (' Utf-8 ') ) file_name = Cmd.split () [1]15 server_response = Client.recv (1024x768) print ("Received response:", Server_response) 17 Client.send ("Received". Encode (' Utf-8 ')) + total_file_size = Int (Server_response.decode ()) Print ("Total", Total_ file_size) F = open (file_name + '. New ', ' WB ') recov_file_size = 022 m = HASHLIB.MD5 () all while R Ecov_file_size < total_file_size:24 if total_file_size-recov_file_size > 1024:25 size = 102 426 else:27 size = total_file_size-recov_file_size28 Print ("Last received", size) 29 #print ("Collect Data ...") 30 data = CLIENT.RECV (size) m.update (data) Recov_file_size + = len (data) f.write (data ) else:35 print ("Finished, size", recov_file_size,total_file_size) f.close () Notoginseng print ("Server-side Send the original MD5 ", Client.recv (1024x768). Decode ()) (" The Final MD5 ", M.hexdigest ())
Start learning SocketseverSocketsever is the most commonly used for the re-encapsulation of sockets is TCP and UDP
Inheritance Relationship:
To create a socket server step:
The following is the rewritten handle:
All client-side interactions with the client are instantiated with a single handle that is processed in handle.
Continue to modify handle add loop: and increase the judgment client exit:
Practice: Server:
1 Import Socketserver 2 class Mytcphandler (Socketserver. Baserequesthandler): 3 def handle (self): 4 while true:5 try:6 self.data = SELF.REQUEST.RECV (1024). Strip () 7 print ("from", self.client_address) 8 Print (self.data) 9 self.request.send (Self.data.upper ()) 10 except Connectionreseterror as e:11 print ("Client exit", E) break13 if __name__ = = "__main__": + HOST, port= "localhost", 999915 server = Socketserver. TCPServer (Host,port), Mytcphandler) server.serve_forever ()
Client
1 Import Socket 2 client = Socket.socket () #声明socket类型 while generating socket connection object 3 #client. Connect ((' 192.168.16.200 ', 9999)) 4 Client.connect (' localhost ', 9999) 5 while true:6 msg = input (">>:"). Strip () 7 If Len (msg) = = 0:continue 8 Client.send (Msg.encode ("Utf-8")) 9 data = CLIENT.RECV (10240) print ("recv:", Data.decode ()) 11 Client.close ()
The above does not support multiple concurrency until now, just write a one-on server
The following write multiple concurrency:Change only one place: 1 use multithreading to achieve
2 using a multi-process implementation: (not WinDOS, not supported, but Linux must work)
some ways to introduce Socketserver:1 return the file descriptor (the system calls itself, we generally do not use)
2 processing a single request is generally not available
3 Keep the request until you receive a definite shutdown (every 0.5 seconds to detect if I sent a shutdown signal)
Call Service_action () to clean up the garbage zombie process after receiving shutdown
4 tell Server_forever () close
5 Reuse of addresses, no waiting for TCP disconnects
Common sock serverserver = Socket.socket () #获得socket实例server. setsockopt (socket. Sol_socket, SOCKET. SO_REUSEADDR, 1) #重用地址
The three processes that are requested can be customized: 1 setup2 handle3 finish
Day8---Multi-threaded socket programming, TCP sticky packet processing