FTP

总则:

  • 将所有功能都拆分开,写成不同模块,便于管理
  • 收发消息要有一个统一的格式,这里为字典形式分为{action, msg}
  • 不要用if判断来调用各个功能,用反射,可以减少代码量并且更美观,后期加功能也更方便
  • cd指令不要使用改变工作路径的方式,否则无法多用户同时使用
  • 文件不要一次全部加载到内存中,而是读一部分传一部分
  • 使用状态码来收发执行情况(存于Setting中)
  •  

     

     

服务端

 目录

 

 代码

 1 import os, sys
 2 import socketserver
 3 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 4 sys.path.append(PATH)
 5 
 6 from core import Start
 7 
 8 if __name__ == '__main__':
 9     s = socketserver.ThreadingTCPServer(Start.ip_port, Start.MyServer)
10     s.serve_forever()
bin
1 import os
2 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
3 
4 buffer_size = 4096
5 ip_port = ('222.195.137.208', 8000)
6 
7 STATUS_CODE = {
8     '201': 'Passed authentication.'
9 }
Setting
  1 import re
  2 import os
  3 import struct
  4 from core import Transmission
  5 from core import File_sys
  6 from config import Setting
  7 
  8 class Cmd:
  9 
 10 
 11     def __init__(self, data, name, conn, mainpath):
 12         self.conn = conn
 13         self.data = data
 14         self.username = name
 15         self.mainpath = mainpath
 16         self.buffer_size = Setting.buffer_size
 17 
 18 
 19     def exit(self):
 20         pass
 21 
 22 
 23     def ls(self):
 24         try:
 25             file = self.data.split(' ')
 26 
 27             if len(file) == 1:
 28                 res = os.listdir(self.mainpath)
 29             elif len(file) == 2:
 30                 res = os.listdir(os.path.join(self.mainpath, file[1]))
 31 
 32             reply = '\n'.join(res).encode('utf8')
 33 
 34             self.conn.sendall(struct.pack('i', len(reply)))
 35             self.conn.sendall(reply)
 36         except Exception as e:
 37             reply = str(e).encode('utf8')
 38             self.conn.sendall(struct.pack('i', len(reply)))
 39             self.conn.sendall(reply)
 40 
 41 
 42     def cd(self):
 43         path_old = self.mainpath
 44         recv_path = self.data.split(' ')
 45         if len(recv_path) == 2:
 46             path = recv_path[1]
 47         else:
 48             return
 49         try:
 50             media = re.findall('\.\.', path)
 51             if media:
 52                 count = 0
 53                 while count < len(media):
 54                     self.mainpath = os.path.dirname(self.mainpath)
 55                     count += 1
 56             else:
 57                 self.mainpath = os.path.join(self.mainpath, path)
 58             if not re.findall(self.username, self.mainpath):
 59                 self.mainpath = path_old
 60         except Exception:
 61             pass
 62 
 63         if not os.path.exists(self.mainpath):
 64             return
 65         else:
 66             return self.mainpath
 67 
 68 
 69     def rm(self):
 70         msg = self.data.split(' ')
 71         if len(msg) == 2:
 72             file = msg[1]
 73             path = os.path.join(self.mainpath, file)
 74             if os.path.exists(path):
 75                 if os.path.isdir(path):
 76                     try:
 77                         os.rmdir(path)
 78                         self.conn.send('1'.encode('utf8'))
 79                     except Exception:
 80                         self.conn.send('300'.encode('utf8'))
 81 
 82                 elif os.path.isfile(path):
 83                     try:
 84                         os.remove(path)
 85                         self.conn.send('1'.encode('utf8'))
 86                     except Exception:
 87                         self.conn.send('300'.encode('utf8'))
 88             else:
 89                 self.conn.send('206'.encode('utf8'))
 90         else:
 91             self.conn.send('201'.encode('utf8'))
 92 
 93 
 94     def mkdir(self):
 95         try:
 96             file = self.data.split(' ')[1]
 97             path = os.path.join(self.mainpath, file)
 98             os.makedirs(path)
 99         except Exception:
100             pass
101 
102 
103     def down(self):
104 
105         try:
106             file = self.data.split(' ')[1]
107             file = os.path.join(self.mainpath, file)
108             file_name = os.path.basename(file)
109             file_path = os.path.dirname(file)
110 
111             if os.path.isdir(file):
112                 msg = '205'
113             elif file_name not in os.listdir(file_path):
114                 msg = '206'
115             else:
116                 msg = 'ready'
117             self.conn.send(struct.pack('i', len(msg)))
118             self.conn.sendall(msg.encode('utf8'))
119 
120             if msg == 'ready':
121                 Transmission.download(self.conn, file)
122 
123         except Exception as e:
124             msg = '201'
125             self.conn.send(struct.pack('i', len(msg)))
126             self.conn.sendall(msg.encode('utf8'))
127 
128 
129     def up(self):
130 
131         filename = self.data['filename']
132         filesize = self.data['filesize']
133         target_path = self.data['target_path']
134 
135         if target_path:
136             abs_path = os.path.join(self.mainpath, target_path, filename)
137         else:
138             abs_path = os.path.join(self.mainpath, filename)
139 
140         File_sys.Logging(abs_path)
141 
142         if os.path.exists(os.path.dirname(abs_path)):
143 
144             if os.path.exists(abs_path):
145                 if os.stat(abs_path).st_size == filesize:
146                     self.conn.send('204'.encode('utf8'))
147                 else:
148                     self.conn.send('801'.encode('utf8'))
149                     Transmission.upload_continue(self.conn, filesize, abs_path)
150 
151             else:
152                 self.conn.send('800'.encode('utf8'))
153                 Transmission.upload(self.conn, filesize, abs_path)
154         else:
155             self.conn.send('203'.encode('utf8'))
Command
  1 import os
  2 import logging
  3 from core import Log
  4 
  5 
  6 def Logging(msg):
  7 
  8     PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'logging.log')
  9 
 10     logger = logging.getLogger()
 11 
 12     fh = logging.FileHandler(PATH)
 13     sh = logging.StreamHandler()
 14 
 15     fm = logging.Formatter('%(asctime)s %(message)s')
 16 
 17     fh.setFormatter(fm)
 18     sh.setFormatter(fm)
 19 
 20     logger.setLevel('INFO')
 21     logger.addHandler(fh)
 22     logger.addHandler(sh)
 23 
 24     logger.info(msg)
 25 
 26     logger.removeHandler(fh)
 27     logger.removeHandler(sh)
 28 
 29 def m_file(name):
 30     path = os.listdir()
 31     count = 0
 32     for file in path:
 33         if file != name:
 34             count += 1
 35     if count == len(path):
 36         os.mkdir(name)
 37     return name
 38 
 39 def make_home(user_name):
 40     home_path = os.path.join(os.getcwd().split('\FTP_server')[0], 'FTP_server')
 41     os.chdir(home_path)
 42     m_file('home')
 43     os.chdir('./home')
 44 
 45     m_file(user_name)
 46     os.chdir('./%s' %user_name)
 47 
 48 def get_path(mainpath):
 49     path0 = mainpath.split('FTP_server')[1].split(os.sep)
 50     path = '/'.join(path0)
 51     return path
 52 
 53 def authenticate(conn, addr, buffer_size):
 54     while True:
 55 
 56         try:
 57             user = conn.recv(buffer_size)
 58             user_ = user.decode('utf8').split(',')
 59 
 60             if len(user_) == 3:
 61                 name = user_[0]
 62                 passwd = user_[1]
 63                 Log.log_in(name, passwd)
 64                 Login_result = True
 65                 break
 66             elif len(user_) == 1:
 67                 break
 68             else:
 69                 name = user_[0]
 70                 passwd = user_[1]
 71 
 72             result = Log.log_out(name, passwd)
 73 
 74             if result == '1':
 75                 log_result = 'Wrong user name'
 76                 conn.sendall(log_result.encode('utf8'))
 77 
 78             elif result == '2':
 79                 log_result = 'Wrong password'
 80                 conn.sendall(log_result.encode('utf8'))
 81             else:
 82                 space = int(result)
 83                 log_result = 'Ready'
 84                 conn.sendall(log_result.encode('utf8'))
 85                 Login_result = True
 86                 break
 87         except Exception as error:
 88             break
 89 
 90     space = int(Log.log_out(name, passwd))
 91 
 92     #Authentication logging
 93     msg = '\nLogin successful !!\nUser: %s\tAddr: %s: %s' % (name, addr[0], addr[1])
 94     Logging(msg)
 95 
 96 
 97     return name, passwd, space, Login_result
 98 
 99 
100 
101 if __name__ == '__main__':
102     get_file('ssy')
File_sys
 1 import os
 2 import struct
 3 import socketserver
 4 import json
 5 
 6 PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 7 os.chdir(os.path.join(PATH, 'core'))
 8 
 9 from core import File_sys
10 from core import Command
11 from config import Setting
12 
13 
14 buffer_size = Setting.buffer_size
15 ip_port = Setting.ip_port
16 
17 class MyServer(socketserver.BaseRequestHandler):
18 
19     def handle(self):
20 
21         Login_result = False
22 
23         #login system
24         name, passwd, space, Login_result = File_sys.authenticate(self.request, self.client_address, buffer_size)
25 
26         # file system
27         File_sys.make_home(name)
28         self.mainpath = os.path.join(Setting.PATH, 'home', name)
29 
30         while Login_result:
31 
32             try:
33                 #send current path
34 
35                 path = File_sys.get_path(self.mainpath)
36                 path_len = len(path)
37                 path_len_struct = struct.pack('i', path_len)
38 
39                 self.request.recv(1)
40 
41                 self.request.send(path_len_struct)
42                 self.request.sendall(path.encode('utf8'))
43 
44                 #receive command
45                 data_json = self.request.recv(buffer_size).decode('utf8')
46                 data = json.loads(data_json)
47 
48                 #logging
49                 log_msg = '\nReceived message:%s' %data
50                 File_sys.Logging(log_msg)
51 
52                 if not data:break
53 
54                 #run command
55                 if len(data) == 1:
56                     cmd = data['action'].split(' ')[0]
57                     data = data['action']
58                 else:
59                     cmd = data['action']
60 
61                 c = Command.Cmd(data, name, self.request, self.mainpath)
62 
63                 if hasattr(c, cmd):
64                     func = getattr(c, cmd)
65                     res = func()
66                     if res:
67                         self.mainpath = res
68 
69             except Exception as e:
70                 File_sys.Logging(e)
71                 break
72 
73 
74 if __name__ == '__main__':
75 
76     s = socketserver.ThreadingTCPServer(ip_port, MyServer)
77     s.serve_forever()
Start
 1 import os
 2 import struct
 3 import json
 4 import hashlib
 5 from config import Setting
 6 from core import File_sys
 7 
 8 buffer_size = Setting.buffer_size
 9 
10 def download(server, file):
11 
12 
13 
14     msg_dic = {}
15     msg_dic['length'] = os.stat(file).st_size
16     msg_dic['name'] = os.path.basename(file)
17 
18     file_msg = json.dumps(msg_dic).encode('utf8')
19 
20     server.send(struct.pack('i', len(file_msg)))
21     server.sendall(file_msg)
22     f = open(file, 'rb')
23     has_send = 0
24     while has_send < msg_dic['length']:
25         data = f.read(buffer_size)
26         server.sendall(data)
27         has_send += len(data)
28 
29     f.close()
30 
31 
32 def upload(conn, filesize, target_path):
33 
34     obj = hashlib.md5()
35 
36     has_recv = 0
37     f = open(target_path, 'ab')
38     while has_recv < filesize:
39         file_data = conn.recv(buffer_size)
40         f.write(file_data)
41         #md5校验
42         obj.update(file_data)
43         has_recv += len(file_data)
44     f.close()
45 
46     MD5 = obj.hexdigest()
47     MD5_recv = conn.recv(buffer_size).decode('utf8')
48 
49     if MD5 == MD5_recv:
50         File_sys.Logging('Upload successed!')
51         conn.send('802'.encode('utf8'))
52     else:
53         File_sys.Logging('Upload failed!')
54         conn.send('803'.encode('utf8'))
55 
56 
57 def upload_continue(conn, filesize, target_path):
58 
59     ans = conn.recv(10).decode('utf8')
60 
61     if ans == 'N':
62         upload(conn, filesize, target_path)
63 
64     elif ans == 'Y':
65         location = os.stat(target_path).st_size
66         conn.sendall(str(location).encode('utf8'))
67 
68         has_recv = 0
69         f = open(target_path, 'ab')
70         while has_recv < filesize-location:
71             file_data = conn.recv(buffer_size)
72             f.write(file_data)
73             has_recv += len(file_data)
74 
75         f.close()
76 
77         File_sys.Logging('Upload successed!')
78         conn.send('802'.encode('utf8'))
79 
80 if __name__ == '__main__':
81     pass
Transmission
 1 import hashlib
 2 import configparser
 3 import os
 4 
 5 def log_in(user, passwd, space=str(100*1024*1024)):
 6 
 7     #加密
 8     my_key = '0822'
 9     obj = hashlib.md5(my_key.encode('utf8'))
10     obj.update(passwd.encode('utf8'))
11 
12     path = os.path.join(os.getcwd().split(os.sep + 'FTP_server')[0], 'FTP_server', 'user.log')
13     #存储用户信息
14     config = configparser.ConfigParser()
15     config[user] = {}
16     config[user]['passwd'] = obj.hexdigest()
17     config[user]['space'] = space
18     with open(path, 'a') as f:
19         config.write(f)
20 
21 def log_out(user, passwd_input):
22 
23     my_key = '0822'
24     config = configparser.ConfigParser()
25     path = os.path.join(os.getcwd().split(os.sep + 'FTP_server')[0], 'FTP_server', 'user.log')
26     config.read(path)
27 
28     try:
29         user_msg = config.items(user)
30         passwd = user_msg[0][1]
31         obj = hashlib.md5(my_key.encode('utf8'))
32         obj.update(passwd_input.encode('utf8'))
33 
34         if obj.hexdigest() == passwd:
35             space = user_msg[1][1]
36             return space
37         else:
38             return '2'
39 
40     except Exception as e:
41         return '1'
42 
43 
44 
45 if __name__ == '__main__':
46     # log_in('ssy', '123456')
47 
48     user = 'ssy'
49     passwd = '123456'
50     result = log_out(user, passwd)
Log
  1 import os
  2 import logging
  3 from core import Log
  4 
  5 
  6 def Logging(msg):
  7 
  8     PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'logging.log')
  9 
 10     logger = logging.getLogger()
 11 
 12     fh = logging.FileHandler(PATH)
 13     sh = logging.StreamHandler()
 14 
 15     fm = logging.Formatter('%(asctime)s %(message)s')
 16 
 17     fh.setFormatter(fm)
 18     sh.setFormatter(fm)
 19 
 20     logger.setLevel('INFO')
 21     logger.addHandler(fh)
 22     logger.addHandler(sh)
 23 
 24     logger.info(msg)
 25 
 26     logger.removeHandler(fh)
 27     logger.removeHandler(sh)
 28 
 29 def m_file(name):
 30     path = os.listdir()
 31     count = 0
 32     for file in path:
 33         if file != name:
 34             count += 1
 35     if count == len(path):
 36         os.mkdir(name)
 37     return name
 38 
 39 def make_home(user_name):
 40     home_path = os.path.join(os.getcwd().split(os.sep + 'FTP_server')[0], 'FTP_server')
 41     os.chdir(home_path)
 42     m_file('home')
 43     os.chdir('./home')
 44 
 45     m_file(user_name)
 46     
 47 
 48 def get_path(mainpath):
 49     path0 = mainpath.split('FTP_server')[1].split(os.sep)
 50     path = '/'.join(path0)
 51     return path
 52 
 53 def authenticate(conn, addr, buffer_size):
 54     while True:
 55 
 56       #  try:
 57             user = conn.recv(buffer_size)
 58             user_ = user.decode('utf8').split(',')
 59 
 60             if len(user_) == 3:
 61                 name = user_[0]
 62                 passwd = user_[1]
 63                 Log.log_in(name, passwd)
 64                 Login_result = True
 65                 break
 66             elif len(user_) == 1:
 67                 break
 68             else:
 69                 name = user_[0]
 70                 passwd = user_[1]
 71 
 72             result = Log.log_out(name, passwd)
 73 
 74             if result == '1':
 75                 log_result = 'Wrong user name'
 76                 conn.sendall(log_result.encode('utf8'))
 77 
 78             elif result == '2':
 79                 log_result = 'Wrong password'
 80                 conn.sendall(log_result.encode('utf8'))
 81             else:
 82                 space = int(result)
 83                 log_result = 'Ready'
 84                 conn.sendall(log_result.encode('utf8'))
 85                 Login_result = True
 86                 break
 87        # except Exception as error:
 88         #    break
 89 
 90     space = int(Log.log_out(name, passwd))
 91 
 92     #Authentication logging
 93     msg = '\nLogin successful !!\nUser: %s\tAddr: %s: %s' % (name, addr[0], addr[1])
 94     Logging(msg)
 95 
 96 
 97     return name, passwd, space, Login_result
 98 
 99 
100 
101 
102 
103 
104 if __name__ == '__main__':
105     get_file('ssy')
File_sys

 

客户端

目录

 

 代码

 1 import os
 2 import struct
 3 from socket import *
 4 import optparse
 5 import Log_in
 6 import Command
 7 import Setting
 8 
 9 class Client:
10 
11     def __init__(self):
12         self.result = True
13         self.op = optparse.OptionParser()
14         self.op.add_option('-i', '--IP', dest='ip')
15         self.op.add_option('-p', '--P', dest='port')
16 
17         options, args = self.op.parse_args()
18         self.verify_args(options, args)
19 
20         self.ip_port = (self.ip, self.port)
21 
22     #命令行中后面添加参数部分(python ),用于指定服务器地址,在此程序中暂时无用
23     def verify_args(self, options, args):
24         ip = options.ip
25         port = options.port
26 
27         if port and ip:
28             if not 0 < int(port) <65535:
29                 exit(Setting.STATUS_CODE['100'])
30             else:
31                 self.port = int(port)
32                 self.ip = ip
33                 Setting.ip_port = (self.ip, self.port)
34         else:
35             self.port = None
36             self.ip = ip
37 
38     def connect(self):
39 
40         self.buffer_size = Setting.buffer_size
41         if not all(self.ip_port):
42             self.ip_port = Setting.ip_port
43 
44         self.client = socket(AF_INET, SOCK_STREAM)
45         self.client.connect(self.ip_port)
46 
47     def interaction(self):
48 
49         client = self.client
50 
51         # login system
52         self.result = Log_in.log(client)
53         os.system('cls')
54 
55         while self.result:
56 
57             # get current path
58             client.send(b'1')
59 
60             path_struct = client.recv(4)
61             path_len = struct.unpack('i', path_struct)[0]
62 
63             path0 = b''
64             while len(path0) < path_len:
65                 path0 += client.recv(path_len)
66             path = path0.decode('utf8')
67 
68             while True:
69 
70                 msg = input('[%s]>>' % path).strip()
71                 if not msg: continue
72 
73                 cmd = Command.CMD(client, msg, self)
74                 cmd_msg = msg.split(' ')[0]
75 
76                 if hasattr(cmd, cmd_msg):
77                     func = getattr(cmd, cmd_msg)
78                     func()
79                     if not cmd.Return:
80                         break
81                     else:
82                         continue
83 
84                 else:
85                     print(Setting.STATUS_CODE['101'])
86                     continue
87 
88         client.close()
89 
90 if __name__ == '__main__':
91 
92     c = Client()
93     c.connect()
94     c.interaction()
bin
  1 import struct
  2 import os
  3 import json
  4 import Transmission
  5 import Setting
  6 
  7 
  8 class CMD:
  9 
 10     def __init__(self, client, msg, Client_self):
 11         self.buffer_size = Setting.buffer_size
 12         self.client = client
 13         self.msg = msg
 14         self.Client_self = Client_self
 15 
 16     def exit(self):
 17         msg = {
 18             'action': self.msg
 19         }
 20 
 21         msg_json = json.dumps(msg)
 22         self.client.send(msg_json.encode('utf8'))
 23         self.Client_self.result = False
 24         self.Return = False
 25 
 26     def help(self):
 27         help_msg = \
 28             ('ls: Lists the files in the current directory.\n'
 29              'cd: Enter the directory.\n'
 30              'mkdir: Make file.\n'
 31              'rm: Remove file.\n'
 32              'down: Download file.\n'
 33              'up: Upload file.\n'
 34              'exit: Login out.')
 35         print("\033[32m%s\033[0m" % help_msg)
 36         self.Return = True
 37 
 38     def ls(self):
 39         client = self.client
 40         buffer_size = self.buffer_size
 41         msg = {
 42             'action': self.msg
 43         }
 44 
 45         msg_json = json.dumps(msg)
 46 
 47         client.send(msg_json.encode('utf8'))
 48         length = struct.unpack('i', client.recv(4))[0]
 49         data = b''
 50         while len(data) < length:
 51             data += client.recv(buffer_size)
 52         print(data.decode('utf8'))
 53         self.Return = False
 54 
 55     def cd(self):
 56         msg = {
 57             'action': self.msg
 58         }
 59 
 60         msg_json = json.dumps(msg)
 61         self.client.send(msg_json.encode('utf8'))
 62         self.Return = False
 63 
 64     def mkdir(self):
 65         msg = {
 66             'action': self.msg
 67         }
 68 
 69         msg_json = json.dumps(msg)
 70         self.client.send(msg_json.encode('utf8'))
 71         self.Return = False
 72 
 73     def rm(self):
 74         msg = {
 75             'action': self.msg
 76         }
 77 
 78         msg_json = json.dumps(msg)
 79         self.client.send(msg_json.encode('utf8'))
 80         result = self.client.recv(self.buffer_size).decode('utf8')
 81         if not result == '1':
 82             print(Setting.STATUS_CODE[result])
 83         self.Return = False
 84 
 85     def down(self):
 86         msg = {
 87             'action': self.msg
 88         }
 89 
 90         msg_json = json.dumps(msg)
 91 
 92         self.client.sendall(msg_json.encode('utf8'))
 93         try:
 94             msg_length = struct.unpack('i', self.client.recv(4))[0]
 95             msg = self.client.recv(msg_length).decode('utf8')
 96 
 97             if msg == 'ready':
 98                 Transmission.download(self.client, self.buffer_size)
 99             else:
100                 print(Setting.STATUS_CODE[msg])
101         except Exception as e:
102             print(e)
103         finally:
104             self.Return = False
105 
106     def up(self):
107 
108         try:
109             cmd_msg = self.msg.split(' ')
110             if len(cmd_msg) == 2:
111                 action, local_path= cmd_msg
112                 target_path = None
113             elif len(cmd_msg) == 3:
114                 action, local_path, target_path = self.msg.split(' ')
115         except Exception:
116             print(Setting.STATUS_CODE['201'])
117         else:
118             try:
119                 filename = os.path.basename(local_path)
120                 filesize = os.stat(local_path).st_size
121             except Exception:
122                 self.Return = True
123                 print(Setting.STATUS_CODE['202'])
124 
125             else:
126                 data = {
127                     'action': 'up',
128                     'filename': filename,
129                     'filesize': filesize,
130                     'target_path': target_path
131                 }
132 
133                 data_json = json.dumps(data)
134                 self.client.sendall(data_json.encode('utf8'))
135 
136                 back_msg0 = self.client.recv(self.buffer_size).decode('utf8')
137                 back_msg1 = Setting.STATUS_CODE[back_msg0]
138 
139                 if hasattr(Transmission, back_msg1):
140                     func = getattr(Transmission, back_msg1)
141                     func(self.client, filesize,local_path)
142                 else:
143                     print(back_msg1)
144 
145 
146 
147                 self.Return = False
Command
 1 import Setting
 2 
 3 buffer_size = Setting.buffer_size
 4 
 5 def log(client):
 6 
 7     count = 0
 8     while True:
 9 
10         if count == 2:
11             msg = 'off'
12             client.send(msg.encode('utf8'))
13             return False
14 
15         while True:
16             name = input('Please input user name:\n').strip()
17             if name:
18                 break
19         while True:
20             passwd = input('Please input passwd:\n').strip()
21             if passwd:
22                 break
23 
24         msg = ('%s,%s' %(name, passwd))
25         if count == 1:
26             msg += ',1'
27 
28         client.send(msg.encode('utf8'))
29 
30         if count == 1:
31             return True
32 
33         result = client.recv(buffer_size).decode('utf8')
34 
35         if result == 'Ready':
36             return True
37         elif result == 'Wrong user name':
38             print(result)
39             media = input('If you want to register new account?(Y/N):\n')
40             if media == 'Y':
41                 count = 1
42                 continue
43             else:
44                 count = 2
45         elif result == 'Wrong password':
46             print(result)
Log_in
 1 import sys
 2 
 3 def bar(count, all):
 4     total = 40
 5     num = int(total*count/all) + 1
 6     num_percent = ' %.1f%%' %(count/all*100)
 7     sys.stdout.write('\r' + '[' + '' * num + '  ' * (total - num) + ']' + num_percent)
 8     if count == all:
 9         sys.stdout.write('\n')
10     sys.stdout.flush()
Process_bar
 1 import os
 2 
 3 PATH = os.path.dirname(os.path.abspath(__file__))
 4 buffer_size = 4096
 5 ip_port = ('222.195.137.208', 8000)
 6 
 7 STATUS_CODE = {
 8     '100': 'Port must in (0, 65535)',
 9     '101': 'Disable instruction, please try again or input help.',
10 
11     '201': 'Invalid input format.',
12     '202': 'Local file not found.',
13     '203': 'Target path invalid.',
14     '204': 'The file already exists, so there is no need to upload it again.',
15     '205': 'Can not download directory.',
16     '206': 'This file or directory is not exist.',
17 
18     '300': 'Can not remove this directory.',
19     '301': 'Can not remove this file.',
20 
21     '800': 'upload',
22     '801': 'upload_continue',
23     '802': 'Upload successed!',
24     '803': 'Upload failed.'
25 }
Setting
 1 import os
 2 import json
 3 import struct
 4 import hashlib
 5 import Process_bar
 6 import Setting
 7 
 8 buffer_size = Setting.buffer_size
 9 
10 def m_file(name):
11     path = os.listdir()
12     count = 0
13     for file in path:
14         if file != name:
15             count += 1
16     if count == len(path):
17         os.mkdir(name)
18     return name
19 
20 def download(client, buffer_size):
21 
22     save_path = m_file('Download')
23 
24     head_len_struct = client.recv(4)
25     head_len = struct.unpack('i', head_len_struct)[0]
26 
27     head = client.recv(head_len).decode('utf8')
28     file_msg = json.loads(head)
29 
30     path = os.path.join(save_path, file_msg['name'])
31     total_len = file_msg['length']
32     has_recv = 0
33     f = open(path, 'ab')
34 
35     while has_recv < total_len:
36         data = client.recv(buffer_size)
37         f.write(data)
38         has_recv += len(data)
39         Process_bar.bar(has_recv, total_len)
40 
41 
42 
43 def upload(client, filesize, local_path):
44 
45     obj = hashlib.md5()
46     f = open(local_path, 'rb')
47     has_send = 0
48 
49     while has_send < filesize:
50         data_file = f.read(buffer_size)
51         client.sendall(data_file)
52         #md5校验
53         obj.update(data_file)
54         has_send += len(data_file)
55         Process_bar.bar(has_send, filesize)
56 
57     f.close()
58     MD5 = obj.hexdigest()
59     client.sendall(MD5.encode('utf8'))
60 
61     result = client.recv(Setting.buffer_size).decode('utf8')
62 
63     print(Setting.STATUS_CODE[result])
64 
65 
66 
67 def upload_continue(client, filesize, local_path):
68 
69     print('The existing file has not been uploaded, whether to continue?(Y/N)')
70     ans = input()
71 
72     if ans in ('Y', 'y'):
73         client.send('Y'.encode('utf8'))
74         print('Continue to upload...')
75 
76         location = int(client.recv(buffer_size).decode('utf8'))
77 
78         f = open(local_path, 'rb')
79         f.seek(location)
80         has_send = location
81 
82         while has_send < filesize:
83             data_file = f.read(Setting.buffer_size)
84             client.sendall(data_file)
85             has_send += len(data_file)
86             Process_bar.bar(has_send, filesize)
87 
88 
89         f.close()
90 
91         result = client.recv(Setting.buffer_size).decode('utf8')
92         print(Setting.STATUS_CODE[result])
93 
94 
95     else:
96         print('Upload again...')
97         client.send('N'.encode('utf8'))
98         upload(client, filesize,local_path)
Transmission

 

总结:

  • 实现的功能可以在Command模块下查看各个函数
  • 给用户分配可存储的额度只完成了分配并记录到账户中,剩下未实现(懒,其实很简单,在每次上传之前进行一次剩余容量的判断就行)
  • 只在上传实现了md5校验,不包括断点续传(如需要实现可将每次update的值存到本地,续传的时候读取就行)
  • 下载未实现断点续传,原理与上传一致就没写了
  • 代码还未做提炼,还存在一些代码重复问题
posted @ 2020-01-05 14:36  Matrixssy  阅读(146)  评论(0编辑  收藏  举报