struct模块

  1.利用struct模块,可以一定程度上解决黏包问题

  认识struct

# 可以模块解决黏包问题
    # struct 模块
        # 该模块可以把一个类型,如数字,转成固定长度的bytes,因为在python中

import struct



ret = struct.pack('i', 4096)    # 'i'代表int   整体意思为把4096数字转换成固定长度的bytes类型

print(ret)  # b'\x00\x10\x00\x00'

num = struct.unpack('i', ret)
print(num)  # (4096,)
print(num[0])   # 4096



import socket

sk = socket.socket()

sk.bind(('127.0.0.1', 8080))

sk.listen()

conn, addr = sk.accept()

while True:
    cmd = input('输入想要客户端windows系统想要执行的命令:')
    conn.send(struct.pack('i', len(cmd)))
    conn.send(cmd.encode('utf-8'))
    recvlen = conn.recv(4)
    recvlen = struct.unpack('i', recvlen)[0]    # 将bytes类型转换为长度
    msg = conn.recv(recvlen).decode('utf-8')
    print(msg)

conn.close()
sk.close()

 

   

 

  

  2.利用struct模块,实现大文件上传

  server.py

import socket
import struct
import json

sk = socket.socket()

sk.bind(('127.0.0.1', 8090))

sk.listen()

conn, addr = sk.accept()

head_len = conn.recv(4)    # 接收报头的长度
head_len = struct.unpack('i', head_len)[0]

bufferlen = 4096

json_head = conn.recv(head_len).decode('utf-8')  # 得到报文, json数据
print(json_head)
head_msg = json.loads(json_head)

filesize = head_msg['filesize']
filename = head_msg['filename']

with open(filename, mode='wb') as f:
    while filesize:
        if filesize >= bufferlen:
            content = conn.recv(bufferlen)
            f.write(content)
            filesize -= bufferlen
        else:
            content = conn.recv(bufferlen)
            f.write(content)
            filesize = 0

sk.close()

  client.py

import socket
import os
import json
import struct

sk = socket.socket()

ip_port = ('127.0.0.1', 8090)

sk.connect(ip_port)

# 报头
head = {'filepath': None,
        'filename' : r'01 python fullstack s9day33 复习.mp4',
        'filesize' : None}

bufferlen = 4096
filepath = r'C:\LocalUserApp'
head['filepath'] = filepath

filesize = os.path.getsize(os.path.join(head['filepath'], head['filename']))

head['filesize'] = filesize

json_head = json.dumps(head)    # 字典转换为字符串
bytes_head = json_head.encode('utf-8')  # 字符串转bytes

# 计算head的长度
head_len = len(bytes_head)  # 报头的长度
pack_head_len = struct.pack('i', head_len)
sk.send(pack_head_len)  # 先发报头的长度
sk.send(bytes_head) # 在发送bytes类型的报头

with open(filepath + r'\\' + head['filename'], mode='rb') as f:
    while filesize:
        if filesize >= bufferlen:
            content = f.read(bufferlen) # 每次从文件读取的内容放到了content
            sk.send(content)
            filesize -= bufferlen
        else:
            content = f.read(filesize)
            sk.send(content)
            filesize = 0

sk.close()

 

posted @ 2018-10-07 12:25  _小溢  阅读(157)  评论(0)    收藏  举报