一. struct模块
该模块可以把一个类型,转换为固定长度的bytes
import struct lst = [1,2,4,3,5,] lst1 = [1,2,4,3,5,7,8,9,] a = struct.pack('i',len(lst))#将列表的长度转化为固定的4字节 b = struct.pack('i',len(lst1)) print(a,len(a)) print(b,len(b))
还可以将想要让服务端/客户端知道的信息做成字典,将字典的长度和字典打包发送 :
符号对应的类型以及转换之后的长度表 :
struct模块实现大文件传输 :
#server端 import socket import struct import json import os sk = socket.socket() sk.bind(('127.0.0.1',8989)) sk.listen() conn,addr = sk.accept() len_dic = struct.unpack('i',conn.recv(4))[0]#unpack解包接受的是元组类型,索引为0是字典的长度 str_dic = conn.recv(len_dic).decode('utf-8')#根据字典的长度将字典接收为字符串类型 dic = json.loads(str_dic)#将字符串类型的字典转换为字典(dict) if dic['opt'] == 'upload': up_load = 'D:\a\b\c\\' + os.path.basename(dic['filename'])#路径拼接 # up_load = os.path.join('D:\a\b\c\\',os.path.basename(dic['filename'])) while dic['filesize'] >0: read_size = conn.recv(2048) with open(os.path.abspath(up_load),mode='ab') as f1: f1.write(read_size) dic['filesize'] -= len(read_size) if dic['opt'] == 'download': down_load = 'D:\a\b\c' conn.send(json.dumps(os.listdir(down_load)).encode('utf-8')) while 1: s = conn.recv(2048).decode('utf-8') file = os.path.abspath(down_load+'/'+s) print(file) if os.path.isdir(file): dic1 = {'tybe':'dir'} len_dic1 = struct.pack('i',len(json.dumps(dic1))) conn.send(len_dic1 + json.dumps(dic1).encode('utf-8')) conn.send(json.dumps(os.listdir(file)).encode('utf-8')) down_load = os.path.abspath(file) continue elif os.path.isfile(file): dic2 = {'tybe':'fil','down_size':os.path.getsize(file)} len_dic2 = struct.pack('i',len(json.dumps(dic2))) conn.send(len_dic2 + json.dumps(dic2).encode('utf-8')) with open(file,mode='rb') as f: down_size = os.path.getsize(file) while down_size: a = f.read(2048) print(a)########### conn.send(a) down_size -= len(a) break
#client端 import socket import struct import os import json sk = socket.socket() sk.connect(('127.0.0.1',8989)) def upload(): dic = {'opt':'upload','filename':None,'filesize':None} file = input('请输入一个想要上传的绝对路径: ') dic['filename'] = file dic['filesize'] = os.path.getsize(file) str_dic = json.dumps(dic) len_dic = struct.pack('i',len(str_dic))#自动将字典的长度转换为4个bytes类型的长度 sk.send(len_dic + str_dic.encode('utf-8')) with open(dic['filename'],mode='rb') as f: while dic['filesize'] > 0: read_size = f.read(2048) sk.send(read_size) dic['filesize'] -= len(read_size) def download(): dic = {'opt':'download','filename':None,'filesize':None} sk.send(struct.pack('i',len(json.dumps(dic)))+json.dumps(dic).encode('utf-8')) while 1: lst = json.loads(sk.recv(2048).decode('utf-8')) for k, v in enumerate(lst, 1): print(k, v) file = input('请根据序号输入想要下载的文件: ') sk.send(lst[int(file) - 1].encode('utf-8')) len_dic = struct.unpack('i',sk.recv(4))[0] str_dic = sk.recv(len_dic).decode('utf-8') if json.loads(str_dic)['tybe'] == 'dir': continue elif json.loads(str_dic)['tybe'] == 'fil': down_file = 'D:\a\b\c\\'+lst[int(file) - 1] while json.loads(str_dic)['down_size']: with open(down_file,mode='ab') as f: down_ = sk.recv(2048) f.write(down_) json.loads(str_dic)['down_size'] -= len(down_) if __name__ =='__main__': lst = ['上传', '下载'] def mai(): for k,v in enumerate(lst,1): print(k,v) c = input('请按序号输入操作: ') if c == '1': upload() if c == '2': download() else: print('输入错误!') mai()