服务器端
# 服务器
import socket
import json
import struct
sk = socket.socket()
sk.bind(("127.0.0.1", 8080)) # 注意双括号
sk.listen() # 监听
conn, addr = sk.accept() # 等待接受客户端的连接 阻塞等待 返回两个值
b_len_dic = conn.recv(4) # 收四个字节内容 是客户端封装的字典的长度信息 以此让服务器知道接收字典的长度 以避免粘包
len_dic = struct.unpack('i', b_len_dic)[0] # 获取到int类型字典的长度,
# 解包,把r解成原数字,结果是一个元组,原数据就在元组的下标位0的位置
str_dic = conn.recv(len_dic).decode('utf-8') # 根据刚才得到的字典长度信息 接收字典
# str_dic = {"opt":menu.get(num),"filename":None,"filesize":None}
dic = json.loads(str_dic) # 将已编码的 JSON 字符串解码为 Python 对象
filename = "new" + dic["filename"] # 新文件名
with open(filename, "ab") as f: # 接收文件 保存文件
while dic['filesize']:
content = conn.recv(1024) # 每次接收1024字节
f.write(content)
dic['filesize'] -= len(content)
conn.close()
sk.close()
客户端
# 客户端
import socket
import os
import json
import struct
sk = socket.socket()
sk.connect(("127.0.0.1", 8080)) # 注意双括号
dic = {"opt": 'upload', "filename": None, "filesize": None} # 字典 {'opt'你要执行的功能, 'filename'文件名, 'content'文件内容}
file_path = input("输入文件的绝对路径:") # 文件的绝对路径
filename = os.path.basename(file_path) # 通过绝对路径获取文件名
filesize = os.path.getsize(file_path) # 通过绝对路径获取文件大小
dic["filename"] = filename # 文件名
dic["filesize"] = filesize # 文件大小
str_dic = json.dumps(dic) # 将 Python对象编码成 JSON字符串
len_dic = len(str_dic) # 获取到字典的长度,是一个int类型的数据
b_len_dic = struct.pack('i', len_dic) # 用一个4bytes的数据表示字典的长度 struct.pack 把一个数字打包成一个四字节的bytes
# struct.pack 把字典的长度信息封装在四个字节中 服务器接收这四个字节来确定接收字典的字节数来避免粘包
sk.send(b_len_dic + str_dic.encode("utf-8")) # 将bytes类型的字典的长度 + bytes类型的字典的内容,一起发送给服务器
with open(file_path, "rb") as f: # 发送文件
while filesize:
content = f.read(1024) # 每次发送1024字节
sk.send(content)
filesize -= len(content)