Python Socketserver實(shí)現(xiàn)FTP文件上傳下載代碼實(shí)例
一、Socketserver實(shí)現(xiàn)FTP,文件上傳、下載
目錄結(jié)構(gòu)
1、socketserver實(shí)現(xiàn)ftp文件上傳下載,可以同時(shí)多用戶登錄、上傳、下載
效果圖:
二、上面只演示了下載,上傳也是一樣的,來不及演示了,上代碼
1、客戶端
import socket,hashlib,os,json,sys,time class Ftpclient(object): def __init__(self): self.client = socket.socket() def connect(self,ip,port): self.client.connect((ip, port)) def help(self): msg=''' ls pwd cd .. get filename put filename ''' print(msg) def interactive(self): """ 客戶端入口 :return: """ while True: verify = self.authenticate() #服務(wù)器端認(rèn)證 if verify: while True: cmd = input('輸入命令 >>').strip() if len(cmd) == 0:continue cmd_str = cmd.split()[0] if hasattr(self,'cmd_%s' %cmd_str): func = getattr(self,'cmd_%s' %cmd_str) func(cmd) else: self.help() def cmd_put(self,*args): """ 上傳文件 :param args: :return: """ cmd_solit = args[0].split() start_time = self.alltime() # 開始時(shí)間 if len(cmd_solit) > 1: filename = cmd_solit[1] if os.path.isfile(filename): filesize = os.stat(filename).st_size msg_dic = { 'filename':filename, 'size':filesize, 'overridden':True, 'action':cmd_solit[0] } self.client.send( json.dumps(msg_dic).encode('utf-8')) server_respinse=self.client.recv(1024) #防止粘包,等服務(wù)器確認(rèn)返回 print('文件開始上傳',server_respinse) client_size = 0 f = open(filename,'rb') for line in f: client_size += self.client.send(line) self.processBar(client_size,filesize) #進(jìn)度條 else: print('文件傳輸完畢,大小為 %s'%client_size) end_time = self.alltime() # 結(jié)束時(shí)間 print('本次上傳花費(fèi)了%s 秒'%self.alltime(end_time,start_time)) f.close() else: print(filename,'文件不存在') else: print('輸入有誤!') def cmd_get(self,*args): """ 下載文件 :param args: :return: """ cmd_solit = args[0].split() start_time = self.alltime() # 開始時(shí)間 filename = cmd_solit[1] if len(cmd_solit) > 1: msg_dic = { 'filename': filename, 'size': '', 'overridden': True, 'action': cmd_solit[0], 'file_exist':'' } self.client.send(json.dumps(msg_dic).encode('utf-8')) self.data = self.client.recv(1024).strip() cmd_dic = json.loads(self.data.decode('utf-8')) print(cmd_dic) if cmd_dic['file_exist']: if os.path.isfile(filename): f = open(filename + '.new', 'wb') else: f = open(filename, 'wb') self.client.send(b'200 ok') #防止粘包,等服務(wù)器確認(rèn)返回 client_size = 0 filesize = cmd_dic['size'] m = hashlib.md5() while client_size < filesize: data=self.client.recv(1024) f.write(data) client_size +=len(data) m.update(data) self.processBar(client_size, filesize) else: print('下載完畢') end_time = self.alltime() # 結(jié)束時(shí)間 print('本次下載花費(fèi)了%s 秒' % self.alltime(end_time, start_time)) f.close() new_file_md5 = m.hexdigest() server_file_md5 = self.client.recv(1024) print('MD5', server_file_md5,new_file_md5) else: print('下載的 %s文件不存在'%filename) else: print('輸入有誤!') def cmd_dir(self,*arge): cmd_solit = arge[0].split() if len(cmd_solit) > 0: msg_dic = { 'action': cmd_solit[0] } self.client.send(json.dumps(msg_dic).encode()) cmd_dir = self.client.recv(1024) print(cmd_dir.decode()) else: print('輸入錯(cuò)誤!') def alltime(self,*args): """ 計(jì)算上傳、下載時(shí)間 :param args: :return: """ if args: return round(args[0] - args[1]) else: return time.time() def processBar(self,num, total): """ 進(jìn)度條 :param num:文件總大小 :param total: 已存入文件大小 :return: """ rate = num / total rate_num = int(rate * 100) if rate_num == 100: r = '\r%s>%d%%\n' % ('=' * int(rate_num /3), rate_num,) else: r = '\r%s>%d%%' % ('=' * int(rate_num /3), rate_num,) sys.stdout.write(r) sys.stdout.flush def authenticate(self): """ 用戶加密認(rèn)證 :return: """ username = input('輸入用戶名:>>') password = input('輸入密碼:>>') m = hashlib.md5() if len(username) > 0 and len(password) >0: username = ''.join(username.split()) password = ''.join(password.split()) m.update(username.encode('utf-8')) m.update(password.encode('utf-8')) m = { 'username':username, 'password':password, 'md5':m.hexdigest() } self.client.send(json.dumps(m).encode('utf-8')) server_user_md5 = self.client.recv(1024).strip() print(server_user_md5.decode()) if server_user_md5.decode() == 'success': print('登錄成功!') return 'ok' else: print('用戶名密碼錯(cuò)誤!') else: print('請輸入用戶名密碼') f = Ftpclient() f.connect('localhost',9999) f.interactive()
2、服務(wù)器端
import socketserver,json,os,hashlib,sys,paramiko import settings class Mysocketserver(socketserver.BaseRequestHandler): def put(self,*args): ''' 接受客戶端上傳文件 :return: ''' cmd_dic = args[0] filename = cmd_dic['filename'] #獲取文件名 filesize= cmd_dic['size'] #獲取文件大?。ㄗ止?jié)) if os.path.isfile(filename): #判斷文件是否存在 f = open(filename + '.new','wb') else: f = open(filename, 'wb') self.request.send(b'200 ok') #防止粘包 print('%s 文件開始上傳' % self.client_address[0]) received_size = 0 while received_size < filesize: data = self.request.recv(1024) f.write(data) received_size += len(data) else: print('文件傳輸完畢',filename) def get(self, *args): ''' 客戶端下載文件 :return: ''' msg_dic = { 'filename': '', 'size': '', 'overridden': True, 'action': '', 'file_exist': '' } cmd_solit = args[0] filename = cmd_solit['filename'] file_exist = os.path.isfile(filename) msg_dic['file_exist'] = file_exist print(file_exist) if file_exist: filesize = os.stat(filename).st_size msg_dic['filename'] = filename msg_dic['size'] = filesize msg_dic['action'] = cmd_solit['action'] self.request.send(json.dumps(msg_dic).encode('utf-8')) server_respang = self.request.recv(1024) #防止粘包 print('開始傳輸',server_respang) f = open(filename,'rb') m = hashlib.md5() for lien in f: m.update(lien) self.request.send(lien) else: print('傳輸完成') f.close() self.request.send(m.hexdigest().encode()) else: print('文件不存在') self.request.send(json.dumps(msg_dic).encode('utf-8')) def client_authentication(self): """ 客戶端認(rèn)證 :return: """ self.client_user= self.request.recv(1024).strip() client_xinxi = json.loads(self.client_user.decode('utf-8')) try: with open(settings.school_db_file + client_xinxi['username'],'rb') as f: data = json.load(f) if data['md5'] == client_xinxi['md5']: #判斷用戶輸入是否和服務(wù)器端MD5是否一致 print('驗(yàn)證成功!') self.request.send('success'.encode()) return 'success' else: self.request.send('error'.encode()) except Exception as e: print('沒有此用戶',e) self.request.send('error'.encode()) def dir(self,*args): """ 查看目錄 :param args: :return: """ cmd_split = args[0] dd=cmd_split['action'] result_os = os.popen(dd).read() self.request.send(result_os.encode()) def handle(self): """ 服務(wù)器端入口 :return: """ while True: try: success = self.client_authentication() if success: self.data=self.request.recv(1024).strip() cmd_dic = json.loads(self.data.decode('utf-8')) action = cmd_dic['action'] if hasattr(self,action): func = getattr(self,action) func(cmd_dic) except ConnectionResetError as e: print('連接斷開',self.client_address[0]) break if __name__ == '__main__': HOST,PORT='localhost',9999 server=socketserver.ThreadingTCPServer((HOST,PORT),Mysocketserver) server.serve_forever()
settings.py 文件
import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) DB_FILE = os.path.join(BASE_DIR, "data\\") school_db_file = os.path.join(DB_FILE) print(school_db_file)
data里兩個(gè)做測試的文件,
alex 文件內(nèi)容:
{"username": "alex", "password": "123456", "md5": "94e4ccf5e2749b0bfe0428603738c0f9"}
kml123456文件內(nèi)容:
{"username": "kml123456", "password": "123456","md5": "a791650e70ce08896e3dafbaa7598c26"}
到這里差不多就沒了,
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Python使用socketServer包搭建簡易服務(wù)器過程詳解
- python網(wǎng)絡(luò)編程:socketserver的基本使用方法實(shí)例分析
- Python通過socketserver處理多個(gè)鏈接
- python如何使用socketserver模塊實(shí)現(xiàn)并發(fā)聊天
- python SocketServer源碼深入解讀
- python利用socketserver實(shí)現(xiàn)并發(fā)套接字功能
- Python探索之SocketServer詳解
- 基于python socketserver框架全面解析
- 利用Python中SocketServer 實(shí)現(xiàn)客戶端與服務(wù)器間非阻塞通信
- Python使用SocketServer模塊編寫基本服務(wù)器程序的教程
- 實(shí)例講解Python中SocketServer模塊處理網(wǎng)絡(luò)請求的用法
- python網(wǎng)絡(luò)編程之TCP通信實(shí)例和socketserver框架使用例子
- python基于socketserver實(shí)現(xiàn)并發(fā),驗(yàn)證客戶端的合法性
相關(guān)文章
利用Python生成文件md5校驗(yàn)值函數(shù)的方法
這篇文章主要給大家介紹了利用Python生成文件md5校驗(yàn)值函數(shù)的方法,文中給出了詳細(xì)的示例代碼,對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,有需要的朋友可以參考借鑒,下面來一起看看吧。2017-01-01兩行代碼解決Jupyter Notebook中文不能顯示的問題
這篇文章主要介紹了兩行代碼解決Jupyter Notebook中文不能顯示的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04python 移動(dòng)圖片到另外一個(gè)文件夾的實(shí)例
今天小編就為大家分享一篇python 移動(dòng)圖片到另外一個(gè)文件夾的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01Python強(qiáng)化練習(xí)之PyTorch opp算法實(shí)現(xiàn)月球登陸器
在面向?qū)ο蟪霈F(xiàn)之前,我們采用的開發(fā)方法都是面向過程的編程(OPP)。面向過程的編程中最常用的一個(gè)分析方法是“功能分解”。我們會(huì)把用戶需求先分解成模塊,然后把模塊分解成大的功能,再把大的功能分解成小的功能,整個(gè)需求就是按照這樣的方式,最終分解成一個(gè)一個(gè)的函數(shù)2021-10-10Python基于Opencv來快速實(shí)現(xiàn)人臉識別過程詳解(完整版)
這篇文章主要介紹了Python基于Opencv來快速實(shí)現(xiàn)人臉識別過程詳解(完整版)隨著人工智能的日益火熱,計(jì)算機(jī)視覺領(lǐng)域發(fā)展迅速,今天就為大家?guī)碜罨A(chǔ)的人臉識別基礎(chǔ),從一個(gè)個(gè)函數(shù)開始走進(jìn)這個(gè)奧妙的世界,需要的朋友可以參考下2019-07-07PyTorch之nn.ReLU與F.ReLU的區(qū)別介紹
這篇文章主要介紹了PyTorch之nn.ReLU與F.ReLU的區(qū)別介紹,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06python操作docx寫入內(nèi)容,并控制文本的字體顏色
今天小編就為大家分享一篇python操作docx寫入內(nèi)容,并控制文本的字體顏色,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02