Network Programming --- subprocess module, struct module, glue package, UDP protocol, socket_server module

Keywords: Linux Operation & Maintenance

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()

Posted by radar on Thu, 25 Nov 2021 10:03:01 -0800