客户端
import os
import json
import struct
import socketsk = socket.socket()
sk.connect(('127.0.0.1',8000))def get_filename(file_path):
return os.path.basename(file_path)operate = ['upload','download']
for num, opt in enumerate(operate,1):
print(num, opt)num = int(input("请输入您要做的操作号:"))
if num == 1:
file_path = input("请输入要上传的文件路径:")
file_size = os.path.getsize(file_path)
file_name = get_filename(file_path)
# 构建字典
dic = {'operate':'upload','filename':file_name,'filesize':file_size} # 序列化为字符串 进行传输
str_dic = json.dumps(dic).encode('utf-8')
ret = struct.pack('i',len(str_dic)) # 把序列化后的字典大小转换成一个4字节的数
sk.send(ret)
sk.send(str_dic)
with open(file_path, 'rb') as f:
while file_size:
content = f.read(1024)
sk.send(content)
file_size -= len(content)
elif num == 2:
"""下载"""
passsk.close()
client.py
服务端
import json
import struct
import socketsk = socket.socket()
sk.bind(('127.0.0.1', 8000))
sk.listen()conn, addr = sk.accept()
# 先接受4个字节,里面装着字典大小
dic_len = conn.recv(4)
dic_len = struct.unpack('i', dic_len)[0] # 取第一个数# 接着接收字典信息
str_dic = conn.recv(dic_len).decode('utf-8')
dic = json.loads(str_dic) # 字典信息if dic['operate'] == 'upload':
with open(dic['filename'], 'wb') as f:
while dic['filesize']:
content = conn.recv(1024)
f.write(content)
dic['filesize'] -= len(content)
conn.close()
sk.close()
service.py
解决粘包的方法就是告诉 socket 接收想要接收到的大小的数据。