server
import socketserver
import struct
import hashlib
import os
import json
class Mysocket(socketserver.BaseRequestHandler):
“”""
接收 字典 文件 信息 长度 字典 文件 信息
判断是否存在未传完的该文件
发送truck类型的数据告知客户端光标位置
最后接收文件
文件传输完毕后发送ok到客户端
salt = ‘salt’
等待客户端发送md5值
验证通过后发送上传结果到客户端
“”"
len_file = 0 # 已经接收文件的长度
md5 = hashlib.md5(b’salt’)
int_head = 0 # file_info 大小
file_info = {} # 文件信息 字典类型 {‘file_name’:’’, ‘file_size’:’’}
file_name = ‘’ # 文件名
file_path = ‘’ # 文件要写入的路径
file_size = 0 # 要接收的文件大小
send_seek = 0 # 发送服务器已经存在光标位置
md5_file_path = ‘’
def file_recv_file(self): # 没有上传过文件 开始上传文件
with open(self.file_path, mode='wb') as f:
while self.len_file < self.file_size: # 数据传输总长度小于 文件大小
file_data = self.request.recv(1024) # 每次接收的数据
f.write(file_data)
self.len_file += len(file_data) # 目前文件总长度
def file_recv_file_have(self): # 接收文件 计算文件md5 写入md5文件
with open(self.file_path, mode='rb+') as f: # 移动光标到send_seek 写入每次收到1024个字节
f.seek(self.send_seek)
while self.len_file < self.file_size: # 数据传输总长度小于 文件大小
file_data = self.request.recv(1024) # 每次接收的数据
f.write(file_data)
self.len_file += len(file_data) # 目前文件总长度
def file_recv_info(self): # 接收 文件信息 给self.file_info赋值
file_info_data = self.request.recv(self.int_head)
self.file_info = json.loads(file_info_data.decode('utf-8'))
def handle(self):
try:
data_head = self.request.recv(4) # 接收 file_info 大小
print(data_head)
self.int_head = struct.unpack('i', data_head)[0] # 头 file_info 长度
self.file_recv_info() # 接收 文件信息 给self.file_info赋值
self.file_name = self.file_info["file_name"]
self.file_size = int(self.file_info["file_size"]) # 给server对象定义文件大小
self.file_path = os.path.join('e:/', self.file_name) # 文件要写入的路径
self.md5_file_path = os.path.join(os.path.dirname(self.file_path),
self.file_name.split('.')[0] + '_md5') # md5文件路径
with open(self.md5_file_path, mode='w', encoding='utf-8') as f:
pass
if not os.path.isfile(self.file_path): # 判断 是否存在文件 如果不存在正常写入
self.request.send(struct.pack('i', 0)) # 发送告知客户端已存在文件长度为0
self.file_recv_file() # 开始接收文件
elif os.path.isfile(self.file_path): # 如果 文件传过一半
with open(self.file_path, mode='rb') as f:
f.seek(0,2)
self.send_seek = f.tell()
self.len_file = os.path.getsize(self.file_path) # 判断 e盘下之前传过的文件大小存入self.len_file中
self.request.send(struct.pack('i', self.send_seek)) # 发送告知客户端已存在文件光标位置为self.send_seek
self.file_recv_file_have() # 开始接收文件
self.request.send('OK'.encode('utf-8')) # 文件传输完毕后发送通知
data_md5 = self.request.recv(1024).decode('utf-8')
with open(self.file_path, 'rb') as f:
for line in f:
self.md5.update(line)
res = self.md5.hexdigest()
if data_md5 == res:
self.request.send('文件上传成功'.encode('utf-8'))
else:
self.request.send('文件上传失败请重新上传'.encode('utf-8'))
except ConnectionResetError as e:
pass
server = socketserver.ThreadingTCPServer((‘192.168.3.7’, 9000), Mysocket)
server.serve_forever()
client
“”""
发送 字典 文件 信息 长度 字典 文件 信息 到服务端
判断是否存在未传完的该文件
发送truck类型的数据告知客户端光标位置
最后接收文件
文件传输完毕后发送ok到客户端
salt = ‘salt’
等待客户端发送md5值
验证通过后发送上传结果到客户端
“”"
import socket
import os
import json
import struct
import hashlib
class Myclient(object):
file_name = ‘’ # 要上传的文件名
file_size = 0 # 要上传的文件大小
head_len = struct.pack(‘i’, 0) # file_info的信息长度 struct格式
json_info_bytes = b’’ # 信息 json 字节
def __init__(self, path):
self.file_path = path # 要上传的文件路径
def file_info(self): # 赋值file_info_bytes
self.file_name = os.path.split(self.file_path)[1]
self.file_size = os.path.getsize(self.file_path)
self.json_info_bytes = json.dumps({"file_name": self.file_name, "file_size": self.file_size}).encode('utf-8')
def head_pack(self): # 赋值4位file_info 的字节长度
self.head_len = struct.pack('i', len(self.json_info_bytes))
def run(self):
self.file_info()
self.head_pack()
return self.head_len + self.json_info_bytes
md5 = hashlib.md5(b’salt’)
while 1:
client = socket.socket()
client.connect((‘192.168.3.7’, 9000))
path = input(‘请输入要上传的文件’)
obj = Myclient(path)
obj.run()
client.send(obj.run())
data_seek = client.recv(4)
print(data_seek)
seek = struct.unpack(‘i’, data_seek)[0]
with open(obj.file_path, mode=‘rb’) as f:
f.seek(seek)
for line in f:
client.send(line)
data_ok = client.recv(1024).decode(‘utf-8’)
if data_ok == ‘OK’:
with open(obj.file_path, mode='rb') as f1:
for line in f1:
md5.update(line)
client.send(md5.hexdigest().encode('utf-8'))
print(client.recv(1024).decode('utf-8'))
经过测试成功,但不够严谨大神们可以指点指点