python 解決粘包現象(struct模塊)
阿新 • • 發佈:2018-08-17
conn bin str 元組 dumps .get struct 下載 pytho
一. 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 importjson 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()
python 解決粘包現象(struct模塊)