Reproduced from: Network Programming --- subprocess module, struct module, glue package, UDP protocol, socket_server module - Remaining person. - Blog Park
Network Programming --- subprocess module, struct module, glue package, UDP protocol, socket_server module
Catalog
subprocess module
Effect:
1. Can help you execute terminal commands of the operating system through code
2. and return the result after the terminal executes the command
import subprocess cmd = input('cmd>>') obj = subprocess.Popen( cmd, shell=True, stderr=subprocess.PIPE, # Return error result parameters stdout=subprocess.PIPE # Return correct result parameters ) result = obj.stdout.read() + obj.stderr.read() print(result.decode('gbk')) # Call cmd directly to work, remember to use gbk decoding
struct module
Is a marker (header) that can compress very long data into a fixed length
import struct #Packaging Compression # i mode, which compresses the length of the data into four bytes import struct str1 = 'dfhkashklfhasfhhlhffihiurue' herders = struct.pack('i',len(str1)) print(herders) # b'\x1b\x00\x00\x00' print(len(herders)) # 4, compressed header length 4 date_len = struct.unpack('i',herders) print(date_len[0]) #Print result as tuple line, value can be taken out by index
Sticky package
Sticking problem
For the first time the server sends data, the client cannot receive it exactly once. The next data sent is glued to the last data.
1. Unable to predict how long the other party will need to receive data size.
2. Data sent several times in succession is small in volume and short in time interval is packaged and sent at one time
TCP protocol features:
TCP is a streaming protocol that packages data that is sent several times in a row with a small amount of data and a short time interval.
Solve sticking problem
--struct module
Headers must be defined, sent, and real data sent
- You want to send both a file and a description of the file # Client sends dictionary to server send_dic = { file_name: file name file_size: Real file length 1000000 } # Serialize bytes data through json module json_data = json.dumps(send_dic) bytes_data = json_data.encode('utf-8') # bytes # Get the header of the dictionary first headers = struct.pack('i', len(bytes_data)) # The server receives the dictionary and the real data of the file
Solutions to the sticking problem
Server: import socket import json import struct server = socket.socket() server.bind( ('127.0.0.1', 9527) ) server.listen(5) while True: conn, addr = server.accept() while True: try: # Receive headers first headers = conn.recv(4) # Unpack to get true data length data_len = struct.unpack('i', headers)[0] # Get the true length of dictionary data bytes_data = conn.recv(data_len) back_dic = json.loads(bytes_data.decode('utf-8')) print(back_dic) except Exception as e: print(e) break conn.close() Client: import socket import struct import json import time client = socket.socket() client.connect( ('127.0.0.1', 9527) ) while True: send_dic = { 'file_name': 'jason Realistic Photo Set.avi', 'file_size': 10000000 # 10G } # json serialization and transcoding to bytes type data json_data = json.dumps(send_dic) bytes_data = json_data.encode('utf-8') # Prepare a headline headers = struct.pack('i', len(bytes_data)) client.send(headers) client.send(bytes_data) time.sleep(10)
Method of uploading large files
Server: import socket import json import struct server = socket.socket() server.bind( ('127.0.0.1', 9527) ) server.listen(5) while True: conn, addr = server.accept() try: # Receive Dictionary Headers First headers = conn.recv(4) # Unpack Get Dictionary Real Data Length data_len = struct.unpack('i', headers)[0] # Get Dictionary Real Data bytes_data = conn.recv(data_len) # Deserialize to get a dictionary back_dic = json.loads(bytes_data.decode('utf-8')) print(back_dic) # Get the file name, file size of the dictionary file_name = back_dic.get('file_name') file_size = back_dic.get('file_size') init_data = 0 # 1. Open the file under its name and prepare it for writing with open(file_name, 'wb') as f: # Receive the file bit by bit and write while init_data < file_size: data = conn.recv(1024) # 2. Start writing video files f.write(data) init_data += len(data) print(f'{file_name}Received!') except Exception as e: print(e) break conn.close() Client import socket import struct import json client = socket.socket() client.connect( ('127.0.0.1', 9527) ) # 1. Open a video file to get the size of the video data with open(r'D:\jason Realistic Photo Set.mp4', 'rb') as f: movie_bytes = f.read() # Close File # 2. Organize a dictionary for video files, which contains the name and size of the video send_dic = { 'file_name': 'jason Realistic Photo Set.mp4', 'file_size': len(movie_bytes) # 10G } # 3. Package the dictionary, send headers, and then send the actual dictionary data json_data = json.dumps(send_dic) bytes_data = json_data.encode('utf-8') headers = struct.pack('i', len(bytes_data)) # Send headers client.send(headers) # Send real dictionary data client.send(bytes_data) # 4. Next send real video file data init_data = 0 num = 1 with open(r'D:\jason Realistic Photo Set.mp4', 'rb') as f: while init_data < len(movie_bytes): # Final acquisition, how much, how much send_data = f.read(1024) print(send_data, num) num += 1 # Send 1024 data at a time client.send(send_data) # For initial send + length of sent data init_data += len(send_data)
UDP Protocol
Definition: UDP is a transport protocol
Characteristic
1. No two-way piping is required
2. No sticking
3. Clients send data to the server without waiting for the server to return a successful result
4. Data is easy to lose and unsafe
Usage method
Server import socket # SOCK_DGRAM: stands for UDP server = socket.socket(type=socket.SOCK_DGRAM) # The server needs to bind ip+port server.bind( ('127.0.0.1', 9527) ) # TCP # conn, addr = server.accept() # conn.recv() # UDP msg, addr = server.recvfrom(1024) msg1, addr1 = server.recvfrom(1024) msg2, addr2 = server.recvfrom(1024) print(msg, msg1, msg2) Client import socket client = socket.socket(type=socket.SOCK_DGRAM) server_ip_port = ('127.0.0.1', 9527) client.sendto(b'hello', server_ip_port) client.sendto(b'hello', server_ip_port) client.sendto(b'hello', server_ip_port) client.sendto(b'hello', server_ip_port) client.sendto(b'hello', server_ip_port)
socket_server module
python built-in module to simplify socket socket server-side code
Simplify TCP and UDP server-side code
You must create a class
Usage method
# Define Classes # TCP: must inherit BaseRequestHandler class class MyTcpServer(socketserver.BaseRequestHandler): # handle of parent class must be overridden def handle(self): while True: try: # 1. Receive messages data = self.request.recv(1024).decode('utf-8') # conn.recv(1024) send_msg = data.upper() self.request.send(send_msg.encode('utf-8')) except Exception as e: print(e) break if __name__ == '__main__': server = socketserver.ThreadingTCPServer( ('127.0.0.1', 8888), MyTcpServer ) # Permanent Execution Service server.serve_forever()