Day30--Python--struct, socketserver

1. struct 
struct.pack 打包
def pack(fmt, *args): # known case of _struct.pack
    """
    pack(fmt, v1, v2, ...) -> bytes
    
    Return a bytes object containing the values v1, v2, ... packed according
    to the format string fmt.  See help(struct) for more on format strings.
    """
    return b""

struct.unpack 解包
def unpack(fmt, string): # known case of _struct.unpack
    """
    unpack(fmt, buffer) -> (v1, v2, ...)
    
    Return a tuple containing values unpacked according to the format string
    fmt.  The buffer's size in bytes must be calcsize(fmt). See help(struct)
    for more on format strings.
    """
    pass

fmt 长度表






# 粘包解决方案_3_服务端     struct.pack  打包

import socket
import struct
import subprocess
import time

server = socket.socket()
ip_port = ('192.168.15.87', 8001)
server.bind(ip_port)
server.listen(3)

while 1:
    print('等待连接中...')
    conn, addr = server.accept()
    print('连接成功!')
    while 1:
        print('等待接收命令...')
        cmd = conn.recv(1024).decode('utf-8')
        if cmd == 'exit':
            break
        sub_obj = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)  # 调用控制台, stdout标准输出,返回信息 stderr 标准错误,返回错误信息
        content = sub_obj.stdout.read()  # 读取标准输出,获取到是gbk编码的bytes
        error = sub_obj.stderr.read()  # 读取标准错误, 也是gbk编码的bytes
        len_of_content = len(content)   # 获取标准输出长度
        len_packed = struct.pack('i', len_of_content)   # 'i'表示打包成4个字节长度. 此处将数据长度打包成4个字节长度的数据 

        len_of_err = len(error)  # 获取标准错误长度
        len_err_packed = struct.pack('i', len_of_err)    # 'i' 表示打包成4个字节长度. 此处将错误信息长度打包成4个字节长度的数据
        # print(len_packed)  # 显示的是字节 b'\xaf\x01\x00\x00'
        if len_of_content == 0:   # 当标准输出长度是零,也就是返回错误信息的时候
            conn.send(len_err_packed)  # 发送打包后的错误信息的长度
            print('数据长度发送成功!')
            conn.sendall(error)      # 循环着发送错误信息数据,防止数据过大造成缓冲区溢出   # 缓冲区大小 8kb  MTU 最大传输单元 1518b, 每次发送数据最好不超过这个数
            print('数据发送成功!')
        else:
            conn.send(len_packed)    # 发送打包后的标准输出信息长度
            print('数据长度发送成功!')  # 循环着发送标准输出信息数据,防止数据过大造成缓冲区溢出
            conn.sendall(content)
            print('数据发送成功!')
    conn.close()
    print('连接已断开!')
    time.sleep(3)
# 粘包解决方案_3_客户端        struct.unpack 解包

import socket
import struct

client = socket.socket()
serverip_port = ('192.168.15.87', 8001)
client.connect(serverip_port)

while 1:
    cmd = input('请输入命令>>>')
    client.send(cmd.encode('utf-8'))
    if cmd == 'exit':
        break
    msg_len_return = client.recv(4)    # 先接收4个字节长度的打包信息
    msg_return_unpacked = struct.unpack('i', msg_len_return)[0]   # 拆包, 获取数据长度
    # print(msg_return_unpacked)   # struct.unpack('i', msg_len_return)返回一个元组 (431,),  取[0]得到长度431

    total_len = 0
    total_data = b''

    while total_len < msg_return_unpacked:
        data_splited = client.recv(1024)     # 分段接收信息,一次最多接收1024,防止超过MTU
        total_data += data_splited       # 把接收到的数据拼接到一起
        total_len += len(data_splited)     #  计算接收到的数据总长度

    print(total_data.decode('gbk'))      # 接收到的信息都是gbk编码的bytes,需要进行解码

client.close()








2. FTP 简单上传

3. socketserver

猜你喜欢

转载自www.cnblogs.com/surasun/p/9811285.html
今日推荐