断点续传 进度条 文件上传

import socketserver
import json
import os
import shutil


CODE = {'1001':'不存在文件,从头开始上传','1002':'断点续传'}
def upload(flie_info,conn,username):
    """
    服务端断点续传
    :param flie_info:
    :param conn:
    :param username:
    :return:
    """
    # 获取文件信息
    md5_val = flie_info.get('md5_val')#获取加密文件的md5字符串
    file_name = flie_info.get('file_name')# 获取文件名
    file_size = flie_info.get('file_info')# 获取文件大小


    file_name_path = os.path.join('home',username,file_name)#文件路径拼接
    file_md5_path = os.path.join('home',username,md5_val)

    # 判断文件是否存在
    if not os.path.exists(file_md5_path):#不存在文件.开始上传完整文件
        response = {'code':1001}
        conn.sendall(json.dumps(response).encode('utf-8'))
        # 不存在MD5加密文件要发送状态码给客户端让他准备(类似于三次握手)


        # 接收完整文件内容并且写到本地
        with open(file_md5_path,'wb') as f:
            recv_data = 0
            while recv_data < file_size:
                data = conn.recv(1024)
                f.write(data)

                recv_data += len(data)
        # 修改文件名
        shutil.move(file_md5_path,file_name_path)
    else:# 存在文件名但是不完整的情况下
        exise_size = os.path.getsize(file_md5_path)
        # 拿到已经存在的文件大小,打包发送给客户端处理

        response = {'code':1002,"size":exise_size}

        conn.sendall(json.dumps(response).encode('utf-8'))
        # 接收到客户端发送的剩余文件内容
        with open(file_md5_path,'ab') as f:
            while exise_size < file_size:
                data = conn.recv(1024)
                f.write(data)
                f.flush()
                exise_size += len(data)
        # 修改文件名
        shutil.move(file_md5_path,file_name_path)
class MyServer(socketserver.BaseRequestHandler):
    def handle(self):
        print('server is waiting.....')
        # 接收命令
        file_json_bytes = self.request.recv(8096)
        file_info = json.loads(file_json_bytes.decode('utf-8'))
        if file_info.get('cmd')=='upload':
            upload(file_info,self.request,'yuanwei')








if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(('127.0.0.1',8003),MyServer)
    server.serve_forever()
import socket
import os
import json
import hashlib

def path_md5(file_path):
    m = hashlib.md5()
    for line in file_path:
        m.update(line)

    return m.hexdigest()

def jdt(size,total_size):
    """
    显示进度条
    :param size:
    :param total_size:
    :return:
    """
    val = int(size/total_size*100)
    print("\r%s%%|%s"%(val,'*'*val),end='')
def send_file(exits_size,total_size):
    """
    发送文件
    :param exits_size: 开始读取字节的位置
    :param total_size: 文件总字节的大小
    :return:
    """
    with open(file_path,'rb')as f:
        f.seek(exits_size)
        while exits_size < total_size:
            data = f.read(1024)
            client.sendall(data)
            exits_size += len(data)
            jdt(exits_size,total_size)
        print('上传成功')
def upload(file_path):
    """
    文件上传(含断点)
    :param file_path:
    :return:
    """
    md5_val = path_md5(file_path)# 获取加密的文件字符串格式
    file_name = os.path.basename(file_path)#获取文件名
    file_size = os.path.getsize(file_path)

    file_info = {'cmd':'upload',
                 'md5_val':md5_val,
                 "file_name":file_name,
                 'file_size':file_size
                 }
    file_json_bytes = json.dumps(file_info).encode('utf-8')
    client.sendall(file_json_bytes)

    response = client.recv(8096).decode('utf-8')

    if response['code'] == 1001:#完整上传
        send_file(0,file_size)
    else:
        exit_size = response['size']
        send_file(exit_size,file_size)

client = socket.socket()
client.connect(('127.0.0.1',8003))

while 1:
    user_inp = input('请输入要执行的命令>>(upload|路径)')

    cmd, file_path = user_inp.strip().split("|")
    if cmd == 'upload':
        upload(file_path)

 

posted on 2018-09-10 21:10  yw1229  阅读(493)  评论(0编辑  收藏  举报

导航