断点传续 # 补充 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
原文地址:https://www.cnblogs.com/llx--20190411/p/11449013.html