打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Python-Socketserver实现FTP,文件上传、下载

一、Socketserver实现FTP,文件上传、下载

 

  目录结构

    

 

 

 

1、socketserver实现ftp文件上传下载,可以同时多用户登录、上传、下载

  效果图:

  

 

二、上面只演示了下载,上传也是一样的,来不及演示了,上代码

  

 

 1、客户端

  1 import socket,hashlib,os,json,sys,time  2   3   4   5 class Ftpclient(object):  6   7   8     def __init__(self):  9         self.client = socket.socket() 10  11     def connect(self,ip,port): 12         self.client.connect((ip, port)) 13  14  15     def help(self): 16         msg=''' 17         ls  18  19         pwd  20          21         cd .. 22          23         get filename 24          25         put filename 26          27         ''' 28         print(msg) 29  30  31     def interactive(self): 32         """ 33         客户端入口 34         :return: 35         """ 36         while True: 37             verify = self.authenticate() #服务器端认证 38             if verify: 39                 while True: 40                     cmd = input('输入命令  >>').strip() 41                     if len(cmd) == 0:continue 42                     cmd_str = cmd.split()[0] 43                     if hasattr(self,'cmd_%s' %cmd_str): 44                         func = getattr(self,'cmd_%s' %cmd_str) 45                         func(cmd) 46                     else: 47                         self.help() 48  49  50     def cmd_put(self,*args): 51         """ 52         上传文件 53         :param args: 54         :return: 55         """ 56         cmd_solit = args[0].split() 57         start_time = self.alltime()  # 开始时间 58         if len(cmd_solit) > 1: 59             filename = cmd_solit[1] 60             if os.path.isfile(filename): 61                 filesize = os.stat(filename).st_size 62                 msg_dic = { 63                     'filename':filename, 64                     'size':filesize, 65                     'overridden':True, 66                     'action':cmd_solit[0] 67                 } 68  69                 self.client.send( json.dumps(msg_dic).encode('utf-8')) 70                 server_respinse=self.client.recv(1024)  #防止粘包,等服务器确认返回 71                 print('文件开始上传',server_respinse) 72                 client_size = 0 73                 f = open(filename,'rb') 74                 for line in f: 75                     client_size += self.client.send(line) 76                     self.processBar(client_size,filesize)  #进度条 77                 else: 78                     print('文件传输完毕,大小为 %s'%client_size) 79                     end_time = self.alltime()              # 结束时间 80                     print('本次上传花费了%s 秒'%self.alltime(end_time,start_time)) 81                     f.close() 82             else: 83                 print(filename,'文件不存在') 84         else: 85             print('输入有误!') 86  87  88     def cmd_get(self,*args): 89         """ 90         下载文件 91         :param args: 92         :return: 93         """ 94         cmd_solit = args[0].split() 95         start_time = self.alltime()  # 开始时间 96         filename = cmd_solit[1] 97         if len(cmd_solit) > 1: 98             msg_dic = { 99                 'filename': filename,100                 'size': '',101                 'overridden': True,102                 'action': cmd_solit[0],103                 'file_exist':''104             }105             self.client.send(json.dumps(msg_dic).encode('utf-8'))106             self.data = self.client.recv(1024).strip()107 108             cmd_dic = json.loads(self.data.decode('utf-8'))109             print(cmd_dic)110             if cmd_dic['file_exist']:111                 if os.path.isfile(filename):112                     f = open(filename + '.new', 'wb')113                 else:114                     f = open(filename, 'wb')115 116                 self.client.send(b'200 ok')     #防止粘包,等服务器确认返回117                 client_size = 0118                 filesize = cmd_dic['size']119                 m = hashlib.md5()120                 while client_size <  filesize:121                     data=self.client.recv(1024)122                     f.write(data)123                     client_size +=len(data)124                     m.update(data)125                     self.processBar(client_size, filesize)126                 else:127                     print('下载完毕')128                     end_time = self.alltime()   # 结束时间129                     print('本次下载花费了%s 秒' % self.alltime(end_time, start_time))130                     f.close()131                     new_file_md5 = m.hexdigest()132                     server_file_md5 = self.client.recv(1024)133                     print('MD5', server_file_md5,new_file_md5)134 135             else:136                 print('下载的 %s文件不存在'%filename)137 138         else:139             print('输入有误!')140 141 142     def cmd_dir(self,*arge):143         cmd_solit = arge[0].split()144         if len(cmd_solit) > 0:145             msg_dic = {146                 'action': cmd_solit[0]147             }148             self.client.send(json.dumps(msg_dic).encode())149             cmd_dir = self.client.recv(1024)150             print(cmd_dir.decode())151 152         else:153             print('输入错误!')154 155 156 157     def alltime(self,*args):158         """159         计算上传、下载时间160         :param args:161         :return:162         """163         if args:164             return round(args[0] - args[1])165         else:166             return time.time()167 168 169     def processBar(self,num, total):170         """171         进度条172         :param num:文件总大小173         :param total: 已存入文件大小174         :return:175         """176         rate = num / total177         rate_num = int(rate * 100)178         if rate_num == 100:179             r = '\r%s>%d%%\n' % ('=' * int(rate_num /3), rate_num,)180         else:181             r = '\r%s>%d%%' % ('=' * int(rate_num /3), rate_num,)182         sys.stdout.write(r)183         sys.stdout.flush184 185 186     def authenticate(self):187         """188         用户加密认证189         :return:190         """191         username = input('输入用户名:>>')192         password = input('输入密码:>>')193         m = hashlib.md5()194         if len(username) > 0 and len(password) >0:195             username = ''.join(username.split())196             password = ''.join(password.split())197             m.update(username.encode('utf-8'))198             m.update(password.encode('utf-8'))199 200             m = {201                 'username':username,202                 'password':password,203                 'md5':m.hexdigest()204             }205             self.client.send(json.dumps(m).encode('utf-8'))206             server_user_md5 = self.client.recv(1024).strip()207             print(server_user_md5.decode())208             if server_user_md5.decode() == 'success':209                 print('登录成功!')210                 return 'ok'211             else:212                 print('用户名密码错误!')213         else:214             print('请输入用户名密码')215 216 217 218 f = Ftpclient()219 f.connect('localhost',9999)220 f.interactive()

2、服务器端

  1 import socketserver,json,os,hashlib,sys,paramiko  2   3 import settings  4   5 class Mysocketserver(socketserver.BaseRequestHandler):  6   7   8   9     def put(self,*args): 10         ''' 11         接受客户端上传文件 12         :return: 13         ''' 14         cmd_dic = args[0] 15         filename = cmd_dic['filename']  #获取文件名 16         filesize= cmd_dic['size']       #获取文件大小(字节) 17  18         if os.path.isfile(filename):    #判断文件是否存在 19             f = open(filename + '.new','wb') 20         else: 21             f = open(filename, 'wb') 22  23         self.request.send(b'200 ok')    #防止粘包 24         print('%s 文件开始上传' % self.client_address[0]) 25         received_size = 0 26         while received_size < filesize: 27             data = self.request.recv(1024) 28             f.write(data) 29             received_size += len(data) 30         else: 31             print('文件传输完毕',filename) 32  33  34     def get(self, *args): 35         ''' 36         客户端下载文件 37        :return: 38        ''' 39         msg_dic = { 40             'filename': '', 41             'size': '', 42             'overridden': True, 43             'action': '', 44             'file_exist': '' 45         } 46  47         cmd_solit = args[0] 48         filename = cmd_solit['filename'] 49         file_exist = os.path.isfile(filename) 50         msg_dic['file_exist'] = file_exist 51         print(file_exist) 52         if file_exist: 53             filesize = os.stat(filename).st_size 54  55             msg_dic['filename'] = filename 56             msg_dic['size'] = filesize 57             msg_dic['action'] = cmd_solit['action'] 58  59             self.request.send(json.dumps(msg_dic).encode('utf-8')) 60             server_respang = self.request.recv(1024)  #防止粘包 61             print('开始传输',server_respang) 62             f = open(filename,'rb') 63             m = hashlib.md5() 64             for lien in f: 65                 m.update(lien) 66                 self.request.send(lien) 67             else: 68                 print('传输完成') 69                 f.close() 70                 self.request.send(m.hexdigest().encode()) 71         else: 72             print('文件不存在') 73             self.request.send(json.dumps(msg_dic).encode('utf-8')) 74  75  76  77     def client_authentication(self): 78         """ 79         客户端认证 80         :return: 81         """ 82         self.client_user= self.request.recv(1024).strip() 83         client_xinxi = json.loads(self.client_user.decode('utf-8')) 84         try: 85             with open(settings.school_db_file + client_xinxi['username'],'rb') as f: 86                 data = json.load(f) 87                 if data['md5'] == client_xinxi['md5']: #判断用户输入是否和服务器端MD5是否一致 88                     print('验证成功!') 89                     self.request.send('success'.encode()) 90                     return 'success' 91                 else: 92                     self.request.send('error'.encode()) 93         except Exception as e: 94             print('没有此用户',e) 95             self.request.send('error'.encode()) 96  97  98     def dir(self,*args): 99         """100         查看目录101         :param args:102         :return:103         """104         cmd_split = args[0]105         dd=cmd_split['action']106         result_os = os.popen(dd).read()107         self.request.send(result_os.encode())108 109 110 111     def handle(self):112         """113         服务器端入口114         :return:115         """116         while True:117             try:118                 success = self.client_authentication()119                 if success:120                     self.data=self.request.recv(1024).strip()121                     cmd_dic = json.loads(self.data.decode('utf-8'))122                     action = cmd_dic['action']123                     if hasattr(self,action):124                         func = getattr(self,action)125                         func(cmd_dic)126             except ConnectionResetError as e:127                 print('连接断开',self.client_address[0])128                 break129 130 131 132 if __name__ == '__main__':133 134     HOST,PORT='localhost',9999135     server=socketserver.ThreadingTCPServer((HOST,PORT),Mysocketserver)136     server.serve_forever()

 

settings.py 文件
1 import os2 3 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))4 5 DB_FILE = os.path.join(BASE_DIR, "data\\")6 7 school_db_file = os.path.join(DB_FILE)8 print(school_db_file)

data里两个做测试的文件,

1 alex 文件内容:2 {"username": "alex", "password": "123456", "md5": "94e4ccf5e2749b0bfe0428603738c0f9"}
kml123456文件内容:{"username": "kml123456", "password": "123456","md5": "a791650e70ce08896e3dafbaa7598c26"}

 

到这里差不多就没了,

 

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Python的下一代http客户端
[接口测试 - http.client篇] 16 基于http.client之POM实战一下
使用python处理excel表格
接口测试框架——第三篇:发送(requests)
python图片处理模块(常用模块与库)
Python操作Word、EXCEL,ACCESS
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服