• 文件断点续传的理解与实现(2)


    先来一张图理解断点续传:

     项目搭建:

    服务端:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    """
    实现文件断点续传的服务器端
    """
    
    import socket
    import os
    
    BASE_DIR = os.path.dirname(os.path.dirname(__file__))
    
    home = os.path.join(BASE_DIR, "home/file")
    sk = socket.socket()
    sk.bind(('127.0.0.1', 8001))
    sk.listen(5)
    
    while True:
        print("Waiting....")
        conn, addr = sk.accept()
        conn.sendall(bytes('欢迎登录', encoding='utf-8'))
        flag = True
        while flag:
            client_bytes = conn.recv(1024)   #接收客户端发送过来的内容
            client_str = str(client_bytes, encoding='utf-8')  #将内容转换成字符串
    
            # 将客户端发送过来的内容以"|"拆分为:命名方法,文件名,文件大小,目标路径
            func, file_name, file_byte_size, targe_path = client_str.split('|', 3)
            file_byte_size = int(file_byte_size)
            path = os.path.join(home, file_name)
            has_received = 0
            #首先判断该路径下是否已存在文件
            if os.path.exists(path):
                conn.sendall(bytes("2003", encoding='utf-8'))  #发送通知客户端,该文件已存在
                is_continue = str(conn.recv(1024), encoding='utf-8')  #等待客户端选择回复
                if is_continue == "2004":
                    has_file_size = os.stat(path).st_size
                    conn.sendall(bytes(str(has_file_size), encoding='utf-8'))  #将已接收的文件大小给客户端
                    has_received += has_file_size
                    f = open(path, 'ab')
                else:
                    f = open(path, 'wb')
            else:
                conn.sendall(bytes("2002", encoding='utf-8'))
                f = open(path, 'wb')
    
            while has_received < file_byte_size:
                try:
                    data = conn.recv(1024)
                    if not data:
                        raise Exception
                except Exception:
                    flag = False
                    break
                f.write(data)
                has_received += len(data)
            print("文件已接收完成!")
            f.close()

    client

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    """
    实现文件断点续传的客户端
    """
    
    import socket
    import sys
    import re
    import os
    FILE_DIR = os.path.dirname(__file__)
    
    ck = socket.socket()
    ck.connect(('127.0.0.1', 8001))
    print(str(ck.recv(1024), encoding='utf-8'))
    
    
    #定义一个函数,计算进度条
    def bar(num = 1, sum = 100):
        rate = float(num) / float(sum)
        rate_num = int(rate * 100)
        temp = '
    %d %%' % (rate_num)
        sys.stdout.write(temp)
    
    while True:
        inp = input('请输入(内容格式:post|文件路径 目标路径): 
     >>> ').strip()  #输入内容格式:命令|文件路径 目标路径
        func, file_path =inp.split("|", 1)  #将输入的内容拆分为两部分,方法名和路径
        local_path, target_path = re.split("s*", file_path, 1) #再将路径部分,通过正则表达式。以空格拆分为:文件路径和上传的目标路径,s*表示匹配任意个空格
        file_byte_size = os.stat(local_path).st_size  #获取文件的大小
        file_name = os.path.basename(local_path)   #设置文件名
    
        post_info = "post|%s|%s|%s" % (file_name, file_byte_size, target_path)  #将发送的内容进行拼接
        ck.sendall(bytes(post_info, encoding='utf-8'))  #向服务器端发送内容
    
        result_exist = str(ck.recv(1024), encoding='utf-8')
        has_sent = 0
        if result_exist == "2003":
            inp = input("文件已存在,是否续传?Y/N:").strip()
            if inp.upper() == 'Y':
                ck.sendall(bytes("2004", encoding='utf-8'))
                result_continue_pos = str(ck.recv(1024), encoding='utf-8')  #已经传输了多少的文件内容
                print(result_continue_pos)
                has_sent = int(result_continue_pos)
    
            else:
                ck.sendall(bytes("2005", encoding='utf-8'))  #发送2005代表不续传
    
        file_obj = open(local_path, 'rb')  #对文件进行读操作
        file_obj.seek(has_sent)  #调整指针
    
        while has_sent < file_byte_size:
            data = file_obj.read(1024)
            ck.sendall(data)
            has_sent += len(data)
            bar(has_sent, file_byte_size)  #进度条
    
        file_obj.close()
        print("文件上传成功!")
    

      

    好好学习,天天向上
  • 相关阅读:
    Spring 增强类型
    Spring IOC及Bean的生命周期
    Spring
    Mybatis注解
    MyBatis关联查询
    LoadRunner(1)
    Selenium(6)
    Selenium(5)
    Selenium(4)
    Selenium(3)
  • 原文地址:https://www.cnblogs.com/topass123/p/12916270.html
Copyright © 2020-2023  润新知