客户端(ftp_client.py)
1 import socketserver,json,hashlib,os 2 from pymongo import MongoClient 3 4 ''' 5 *****要点***** 6 1.面向对象编程 7 2.反射的利用 8 3.代码的高度解耦 9 4.md5加密传输认证 10 5.数据库查询验证 11 ************** 12 ''' 13 db = MongoClient('localhost', 27017) 14 curent_document = '' 15 #此类用于处理一系列客户端请求 16 class deal(): 17 def __init__(self,name): 18 self.name = name 19 20 #用户登录认证 21 def deal_login(self,data,client): 22 global logined_uname,db 23 BASE_DIR = ''#基目录 24 #选择数据库 25 d = db['DB_FOR_PYTHON'] 26 #选择集合 27 users = d['FTP_USERS'] 28 name = data['name'] 29 pwd = data['pwd'] 30 u = users.find_one({'name':name ,'pwd':pwd}) 31 #用户不存在,返回0 32 if u == None or u == '': 33 #使用find()和find_one返回的结果分别是cursor和一条记录 34 u1 = users.find_one({'name':name}) 35 if u1 == None or u1 == '': 36 #无此用户 37 client.send(b'0') 38 return '0'.encode() 39 else: 40 #密码有误 41 client.send(b'2') 42 return '2'.encode() 43 else: 44 #登录成功 45 client.send(b'1') 46 logined_uname = name 47 return '1'.encode() 48 49 #上传处理 50 def deal_upload(self,data,request): 51 #查出用户的磁盘配额大小,并检查用户上传文件大小,和要上传的文件加以对比,看是否可以继续上传 52 user1 = db.DB_FOR_PYTHON.FTP_USERS.find_one({'name':logined_uname}) 53 #用户的磁盘配额大小 54 space_limite = user1['space'] 55 print('当前用户磁盘总空间:{}'.format(str(space_limite))) 56 name = data['name'] 57 #上传文件大小 58 totalsize = data['size']*1024 59 m = hashlib.md5() 60 request.send('ok'.encode()) 61 cur_size = 0 62 cur_content =b'' 63 size = 0 64 global BASE_DIR 65 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 66 file_name = '' 67 #剩余磁盘大小 68 space = 0 69 u_dir = BASE_DIR+os.sep+'USERS_HOME'+os.sep+logined_uname.upper()+"_HOME" 70 if os.path.exists(u_dir): 71 # 用户总目录文件夹大小(bit计算) 72 real_space = (os.stat(u_dir).st_size)*1024 73 space = space_limite - real_space 74 file_name = u_dir+os.sep+name 75 else: 76 os.mkdir(u_dir) 77 space = space_limite 78 file_name = u_dir + os.sep + name 79 #如果上传资源的大小小于等于磁盘剩余空间,则继续 80 if space >= totalsize: 81 print('可以发送') 82 f = open(file_name,'wb') 83 while cur_size < totalsize: 84 if totalsize - cur_size >1024*1024: 85 size = 1024*1024 86 else: 87 size = totalsize - cur_size 88 print(size) 89 data = request.recv(size) 90 m.update(data) 91 cur_content += data 92 f.write(data) 93 cur_size += len(data)*1024 94 else: 95 print('haha') 96 f.close() 97 request.send(json.dumps({'state':'upload success!','md5':m.hexdigest()}).encode()) 98 return json.dumps({'state':'upload success!','md5':m.hexdigest()}).encode() 99 else: 100 request.send(json.dumps({'state':'upload fail,your filesize exceeding the rest of your own space!','rest':space,'filesize':totalsize,'md5':None}).encode()) 101 return json.dumps({'state':'upload fail,your filesize exceeding the rest of your own space!','rest':space,'filesize':totalsize,'md5':None}).encode() 102 #下载实现 103 def deal_download(self,data): 104 self.data = data['name'] 105 return self.data 106 #用户切换目录 107 def deal_cd(self,data): 108 global BASE_DIR,curent_document 109 #当前用户基目录 110 ROOT_DOC = BASE_DIR+os.sep+'USERS_HOME'+os.sep+logined_uname.upper()+"_HOME" 111 current_document = ROOT_DOC 112 #用户输入的目录 113 manual_enter = data['cd_document'] 114 current_document = os.chdir(manual_enter) if os.path.exists(manual_enter) else curent_document 115 print("用户要跳转的目录:",current_document) 116 pass 117 #查看文件 118 def deal_dir(self): 119 pass 120 #断点续传功能 121 def deal_cont(self): 122 pass 123 #面向对象的方式实现 124 class ftp_server(socketserver.BaseRequestHandler): 125 def handle(self): 126 logined_uname = '' 127 while True: 128 try: 129 #接收来自客户端的信息 130 data = self.request.recv(1024).decode() 131 data = json.loads(data) 132 print(data) 133 cmd = data['req'] 134 #创建服务端对象 135 d = deal('ser') 136 if hasattr(d,cmd): 137 c = getattr(d,cmd) 138 res = c(data,self.request).decode() 139 print(res) 140 except ConnectionResetError as e: 141 print('error:',e) 142 break 143 144 #主方法入口 145 if __name__ == '__main__': 146 HOST,PORT = 'localhost',9999 147 server = socketserver.ThreadingTCPServer((HOST,PORT),ftp_server) 148 server.serve_forever()
服务端(ftp_server.py)
1 # coding = utf-8 2 3 import socket,json,re,os,hashlib 4 login_uname = '' 5 class client_do(object): 6 def __init__(self,name): 7 self.name = name 8 #登录 9 def deal_login(self,data,client): 10 try: 11 global login_uname 12 global state 13 name = data.split()[1].split('\')[0] 14 pwd = data.split()[1].split('\')[1] 15 req = data.split()[0] 16 data = { 17 'req':req, 18 'name':name, 19 'pwd':pwd 20 } 21 client.send(json.dumps(data).encode()) 22 response = client.recv(1024).decode() 23 if response == '1': 24 login_uname = name 25 global lg_s 26 lg_s = '