• 断点传续 # 补充 mysql


    断点传续   # 补充 mysql

     1 断点续传
     2 
     3 任务进行过程中,由于某些原因导致任务没有完成
     4 在重新启动程序之后 可以接着上次断掉的位置继续传输
     5 
     6 ===========    ================  服务器
     7 =========== 50
     8                ================
     9 
    10 
    11 1.客户端  需下载某个文件
    12     输入一个文件名称
    13     判断该文件是否已经下载
    14     判断文件是否传输完毕
    15     一个任务存在的状态
    16 
    17 
    18     1.新任务   本地没有
    19         文件不存在   并且任务记录中也不存在
    20     2.任务未完成  本地有 但是不完整
    21         文件已经存在 但是任务记录标记为未完成
    22     3.任务已完成  本地有完整的数据
    23          文件已经存在 任务标记为已完成
    24     4.任务已经完成 但是数据被删除
    25          文件不存在  任务标记为完成
    26 
    27     任务记录?
    28         新任务 需要添加到记录中   未完成
    29         下载完成 修改记录为完成
    30         需要哪些数据?
    31             任务名称
    32                 文件名称
    33             状态
    34                 未完成
    35                 已完成
    36         {"name":False}
    37 
    38         字典存储任务 需要永久存储
    39 
    40 
    41 
    42 使用方法
    43 将测试文件放在服务器的 serverFiles中
    reademe
    1 {"5.u534fu7a0b.mp4": true}
    file_long.text
     1 import json
     2 import os
     3 import socket
     4 
     5 import struct
     6 
     7 import logging
     8 
     9 server = socket.socket()
    10 
    11 server.bind(("127.0.0.1",1688))
    12 server.listen()
    13 
    14 
    15 def recv_head(client):
    16     head_len = client.recv(4)
    17     if not head_len:
    18         raise Exception("对方下线了!")
    19     lens = struct.unpack("i",head_len)[0]
    20     req = json.loads(client.recv(lens).decode("utf-8"))
    21     return req
    22 
    23 
    24 def send_rep(client,rep):
    25     jdata = json.dumps(rep).encode("utf-8")
    26     client.send(struct.pack("i",len(jdata)))
    27     client.send(jdata)
    28 
    29 while True:
    30     client,addr = server.accept()
    31     while True:
    32         try:
    33             req = recv_head(client)
    34             # rep中必须包含 文件名称
    35             filename = req["filename"]
    36 
    37 
    38             path = os.path.join("serverFiles",filename)
    39             if not os.path.exists(path):
    40                 rep = {"msg":"服务器不存在该文件!"}
    41                 send_rep(client,rep)
    42             else:
    43                 # 发送文件信息
    44                 info = {"filename":filename,"filesize":os.path.getsize(path)}
    45                 send_rep(client,info)
    46 
    47                 # 发送文件数据
    48                 with open(path,"rb") as f:
    49                     f.seek(req["recv_size"],0)
    50                     while True:
    51                         data = f.read(2048)
    52                         if not data :break
    53                         client.send(data)
    54                 # 文件传输完毕
    55                 print("文件传输完毕!")
    56                 client.close()
    57                 break
    58         except Exception as e:
    59             logging.error(e)
    60             client.close()
    61             break
    server.py
      1 import os
      2 
      3 import time
      4 from mylib import *
      5 import socket
      6 
      7 
      8 
      9 
     10 
     11 
     12 
     13 
     14 
     15 
     16 
     17 
     18 
     19 
     20 
     21 # 用于处理任务状态的工具类
     22 class LogTool:
     23     # 日志记录的文件名称
     24     log_file = "file_log.txt"
     25     # 初始化方法
     26     def __init__(self):
     27         #创建 记录文件
     28         if not os.path.exists(self.log_file):
     29             self.write_info({})
     30 
     31     # 用于获取文件状态的方法
     32     def get_file_status(self,filename):
     33         """
     34         :param filename:
     35         :return: 1 表示完成  0 已存在但表示未完成  2 新任务  3 文件被删除
     36         """
     37         # 先找任务记录看看
     38         info = self.read_info()
     39         if filename in info:  #存在记录
     40             if info[filename]:
     41                 # 记录显示为True 在判断文件是否已经存在
     42                 if os.path.exists(os.path.join("clientFiles",filename)):
     43                     return 1
     44                 else:
     45                     return 3
     46             else:
     47                 return 0
     48         else:# 不存在记录
     49             return 2
     50 
     51     def read_info(self):
     52         with open(self.log_file,"rt") as f:
     53             return json.load(f)
     54 
     55     def write_info(self,info):
     56         with open(self.log_file,"wt") as f:
     57             json.dump(info,f)
     58 
     59     # 添加新的新记录
     60     def newtask(self,filename):
     61         info = self.read_info()
     62         info[filename] = False
     63         self.write_info(info)
     64 
     65     #标记为任务完成
     66     def task_done(self, filename):
     67         info = self.read_info()
     68         info[filename] = True
     69         self.write_info(info)
     70 
     71 
     72 # =======================================TCP 部分
     73 
     74 
     75 
     76 
     77 
     78 # 输入文件名称
     79 filename = input("filename:").strip()
     80 
     81 # 创建小工具
     82 tool = LogTool()
     83 
     84 # 获取任务的状态
     85 st = tool.get_file_status(filename)
     86 # "  :return: 1 表示完成  0 已存在但表示未完成  2 新任务  3 文件被删除"
     87 
     88 # 表示已经下载的大小
     89 recv_size = 0
     90 
     91 if st == 0:
     92     # 要断点续传 要读取文件大小发给服务器
     93     recv_size = os.path.getsize(os.path.join("clientFiles",filename))
     94 elif st == 1:
     95     print("该任务已经完成!")
     96     exit()
     97 elif st == 2:
     98     print("新任务")
     99 else:
    100     if input("文件被删除!是否重新下载?(y/n)") != "y":
    101         exit()
    102 
    103 # 信息中要包含已接受文件大小
    104 info = {"filename":filename,"recv_size":recv_size}
    105 
    106 
    107 client = socket.socket()
    108 client.connect(("127.0.0.1",1688))
    109 
    110 # 发送报头信息
    111 send_rep(client,info)
    112 
    113 # 接收报头信息
    114 rep = recv_head(client)
    115 
    116 
    117 # 判断是文件信息还是错误信息 
    118 if "filename" in rep:
    119     # 拼接文件路径
    120     path = os.path.join("clientFiles", rep["filename"])
    121 
    122 
    123     buff_size = 2048
    124 
    125     # 添加下载记录
    126     tool.newtask(filename)
    127 
    128     # 注意 必须使用ab模式 才能断点续传
    129     with open(path,"ab") as f:
    130         while recv_size < rep["filesize"]:
    131             if buff_size < rep["filesize"] - recv_size:
    132                 data = client.recv(buff_size)
    133             else:
    134                 data = client.recv(rep["filesize"] - recv_size)
    135             f.write(data)
    136             recv_size += len(data)
    137             # print(recv_size/rep["filesize"])
    138 
    139     # 标记完成
    140     tool.task_done(filename)
    141 
    142 else:
    143     print("error")
    144     print(rep)
    145 
    146 
    147 
    148 
    149 
    150 
    151 
    152 # 发送文件报头
    client.py
     1 import json
     2 import struct
     3 def recv_head(client):
     4     head_len = client.recv(4)
     5     if not head_len:
     6         raise Exception("对方下线了!")
     7     lens = struct.unpack("i", head_len)[0]
     8     req = json.loads(client.recv(lens).decode("utf-8"))
     9     return req
    10 
    11 
    12 def send_rep(client,rep):
    13     jdata = json.dumps(rep).encode("utf-8")
    14     client.send(struct.pack("i",len(jdata)))
    15     client.send(jdata)
    mylib.py
  • 相关阅读:
    如何将自己的镜像上传到私库
    基于spring-cloud的微服务(1) 服务注册中心eureka
    关于对象池技术的一些记录
    为Docker容器中运行的gitlab添加ssh的一些问题记录
    使用java实现的socket代理(支持socket4和socket5)
    ConfluenceRemoteUserAuth
    JiraRemoteUserAuth
    Apache 的mod_auth_cas模块的介绍和使用
    基于乌班图的标准镜像添加中文支持
    apache反向代解决绝对路径可能出现的问题
  • 原文地址:https://www.cnblogs.com/llx--20190411/p/11449013.html
Copyright © 2020-2023  润新知