首頁 後端開發 Python教學 簡單FTP的實作詳解

簡單FTP的實作詳解

Jun 21, 2017 pm 04:47 PM
python 一天 作業 簡單

 

作业要示:

开发简单的FTP:
1. 用户登陆
2. 上传/下载文件
3. 不同用户家目录不同
4. 查看当前目录下文件
5. 充分使用面向对象知识

 

 

 REDMAE

 1 用户登陆 2  3 1、查看用户目录文件 4 2、上传文件, 5 3、下载方件 6 4、退出 7  8 程序结构: 9 socket_server_client/#程序目录10 |- - -clients/#client程序主目录11 |      |- - -__init__.py12 |      |- - -bin/#启用目录13 |      |       |- - - __init__.py14 |      |       |- - -socket_client.py#客户端启动15 |      |16 |      |- - -cfg/#配置文件目录17 |      |       |- - - __init__.py18 |      |       |- - -config.py#配置文件19 |      |20 |      |- - -core/#主要程序目录21 |      |       |- - - __init__.py22 |      |       |- - -client_func.py#主要函数23 |      |24 |      |- - -home/#客户端下载文件目录25 |26 |- - -servers/#server程序主目录27 |      |- - -__init__.py28 |      |- - -bin/#启用目录29 |      |       |- - - __init__.py30 |      |       |- - -registration.py#用户注册31 |      |       |- - -socket_server.py#服务端启动32 33 |      |34 |      |- - -cfg/#配置文件目录35 |      |       |- - - __init__.py36 |      |       |- - -config.py#配置文件37 |      |38 |      |- - -core/#主要程序目录39 |      |       |- - - __init__.py40 |      |       |- - -server_classc.py#主要函数41 |      |42 |      |- - -db/#用户上传文件主目录43 |              |- - -user_file/#用户上传目录44 |              |- - -user_names#注册用户文件45 |
登入後複製

 

服务端

servers/

    bin/

registration.py

 1 #!usr/bin/env python 2 #-*-coding:utf-8-*- 3 # Author calmyan 4 import socket,os,json,sys,pickle 5  6 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量 7 sys.path.append(BASE_DIR)#增加环境变量 8 from cfg import config 9 print('用户注册'.center(60,'='))10 while True:11     user_=input('请输入您要注册的用户名:').strip()12     user_dir=os.path.join(config.USER_DIR,user_)#拼接用户目录路径13     if os.path.isdir(user_dir):# 判断一个目录是否存在14         print('用户已经存在请重输!')15         continue16     else:17         pwd_=input('请输入密码:').strip()18         pwd_two=input('请确认密码:').strip()19         if pwd_==pwd_two:20             try:21                 os.mkdir(user_dir)#创建目录22             except Exception as e:23                 print(e)24                 continue25             finally:26                 file_dir=user_dir+'\\user'#用户目录下的用户名文件27             if  not os.path.isfile(config.USER_FILE):28                 with open(config.USER_FILE,'w',encoding='utf-8') as f:29                     f.write('{}')30             with open(config.USER_FILE,'r+',encoding='utf-8') as f:31                 data=eval(f.readline())32                 data[user_]=pwd_33                 f.seek(0)34                 f.write(str(data))35             print('用户[%s]注册成功!'%user_)36             exit()
登入後複製
View Code

socket_server.py

 1 #!usr/bin/env python 2 #-*-coding:utf-8-*- 3 # Author calmyan 4 import socket,os,json 5 import sys 6 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量 7 sys.path.append(BASE_DIR)#增加环境变量 8  9 from  core.server_class import listen_func10 s=socket.socket()#定义11 s.bind(('localhost',9000))#绑定要监听的 端口12 s.listen(5)#对列513 print('正在监听中')14 listen_func(s)
登入後複製

cfg/

config.py

 1 #!usr/bin/env python 2 #-*-coding:utf-8-*- 3 # Author calmyan 4 import os ,sys 5 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量 6 sys.path.append(BASE_DIR)#增加环境变量 7  8  9 USER_DIR=BASE_DIR+'\db\\user_file\\'#定义用户目录文件路径变量10 11 USER_FILE=BASE_DIR+'\db\\user_names'#定义用户文件路径变量
登入後複製
View Code

 

core/

server_class.py

  1 #!usr/bin/env python  2 #-*-coding:utf-8-*-  3 # Author calmyan  4 import socket,os,json,sys,pickle  5   6 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量  7 sys.path.append(BASE_DIR)#增加环境变量  8   9 from cfg import config 10  11  12 #用户名检测函数 13 def open_file_list(name,pas):#传入当前类 14     with open(config.USER_FILE,'r',encoding='utf-8') as f: 15         data=eval(f.readline()) 16         if name in data and pas==data[name]: 17             return True 18         else: 19             return False 20  21  22 #连接类 23 class socket_server(object): 24     '''连接类''' 25     file_path=config.USER_DIR#用户路经变量 26     def __init__(self,data,conn):#传入用户名,密码 27         self.DATA=data 28         self.conn=conn 29  30  31     def show_process(self,lens): 32         received_size=0#定义大小 33         current_percent=0#当前大小百分比 34         while received_size<lens: 35             if int((received_size/lens)*100)>current_percent: 36                 print('#',end='',flush=True) 37                 current_percent=int((received_size/lens)*100) 38             new_size=yield 39             received_size+=new_size 40  41     def ret_l(self): 42         ret=socket_server.login(self.DATA["name"],self.DATA['pwd'],self.conn)#用户名检测 43         return ret 44     def open_f(self,ret):#打开目录 45         file_dir=os.path.join(socket_server.file_path,ret['data']['user'])#用户目录 46         file_name=os.listdir(file_dir)#目录文件列表 47         f=file_dir+self.DATA['filename']##上传的文件名 48         return file_dir,file_name,f#返回 49  50     def ls_file(self,data):#查看文件 51         self.conn.send(json.dumps(data[1]).encode()) 52  53     def send_file(self,data): 54  55         if self.DATA['filename'] in data[1]: 56             f=data[0]+'/'+self.DATA['filename'] 57             file_obj=open(f,"rb")#打开文件 58             name=file_obj.name.split('/')[-1]#文件名 59             sez=os.path.getsize(f)#获取文件大小 60             print(sez) 61             data_header={ 62                     "action":"put", 63                     "filename":name, 64                     "size":sez 65                     } 66             self.conn.send(json.dumps(data_header).encode())#用json 序列化后,发送相关 信息 67             for line in file_obj: 68                 self.conn.send(line)#发送数据 69  70         elif self.DATA['filename'].isdigit(): 71             num=int(self.DATA['filename'])#转为数字 72             try: 73                 f=data[0]+'/'+data[1][num]# 74                 file_obj=open(f,"rb")#打开文件 75                 name=file_obj.name.split('/')[-1]#文件名 76                 sez=os.path.getsize(f)#获取文件大小 77                 print(sez) 78                 data_header={ 79                 "action":"put", 80                 "filename":name, 81                 "size":sez 82                 } 83                 self.conn.send(json.dumps(data_header).encode())#用json 序列化后,发送相关 信息 84                 for line in file_obj: 85                     self.conn.send(line)#发送数据 86                 self.conn.send(json.dumps(f).encode())#发送文件 87             except Exception as e: 88                 data={'filename':False} 89                 self.conn.send(json.dumps(data).encode()) 90         else: 91             data={'filename':False} 92             self.conn.send(json.dumps(data).encode()) 93     def put_file(self,data):#上传文件 94         file_obj=open(data[2],'wb')#打开新建 这个文件 95         rece_size=0#定义 文件大小值 96         #prten=socket_server.show_process(self.DATA["size"]) 97         #prten.__next__() 98         while rece_size<self.DATA["size"]:#小于接收的文件大小时, 99             recv_data=self.conn.recv(4096)100             file_obj.write(recv_data)#写入文件101             rece_size+=len(recv_data)#增加文件大小计算102 103         else:104             print("文件[%s]接收完毕!"%self.DATA["filename"])105             file_obj.flush()106             file_obj.close()#关闭文件107 108 109     @staticmethod110     def login(name,pas,conn):#用户检测 函数111         try:112             if open_file_list(name,pas):113                 tag=True114                 error=&#39;&#39;115                 datas={&#39;user&#39;:name}116                 data={&#39;mag&#39;:&#39;用户认证通过&#39;,&#39;tag&#39;:True}117                 print(json.dumps(data).encode())118                 conn.send(json.dumps(data).encode())119             else:120                 raise Exception(&#39;\033[41;1m用户名或密码错误\033[0m&#39; %name)121         except Exception as e:122             tag=False123             error=str(e)124             datas=&#39;&#39;125             data={&#39;mag&#39;:&#39;用户或密码错误&#39;,&#39;tag&#39;:False}126             print(&#39;发送数据%s&#39;%data)127             conn.send(json.dumps(data).encode())128         return {&#39;tag&#39;:tag,&#39;error&#39;:error,&#39;data&#39;:datas}129 130 #监听函数131 def listen_func(s):132     while True:133         conn,client_addr=s.accept()#端口监听中....返回两个值 ,联接编号对象 , ip134         print(&#39;获取到新连接:&#39;,client_addr)135         while True:136             data=conn.recv(4096)#接收数据 指令137             print(&#39;接收的数据:&#39;,data)138             data= json.loads(data.decode())#反序列139             if len(data)==0:140                 break141             if data[&#39;action&#39;]==&#39;user&#39;:#如果是用户名,进行认证\142                 serv=socket_server(data,conn)143                 ret=serv.ret_l()144             if ret[&#39;tag&#39;]:145                 pass146             else:147                 continue148 149             print(data)150             if data[&#39;action&#39;]=="put":#如果接收的字典中是put,就是进行接收151                 serv=socket_server(data,conn)152                 serv.put_file(serv.open_f(ret))#调对象方法153             elif data[&#39;action&#39;]==&#39;get&#39;:#下载154                 serv=socket_server(data,conn)#实例化155                 serv.send_file(serv.open_f(ret))#调 用方法156             elif data[&#39;action&#39;]==&#39;ls&#39;:#查看157                 serv=socket_server(data,conn)158                 serv.ls_file(serv.open_f(ret))159                 continue
登入後複製
View Code

客户端

clients/

bin/

socket_client.py

  1 #!usr/bin/env python  2 #-*-coding:utf-8-*-  3 # Author calmyan  4   5 import socket,os,json,sys  6 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量  7 sys.path.append(BASE_DIR)#增加环境变量  8 from core.client_func import user_pwd  9 #from core.client_func import show_process 10 from cfg import config 11  12 #进度条 13 def show_process(lens): 14     received_size=0#定义大小 15     current_percent=0#当前大小百分比 16     while received_size<lens: 17         if int((received_size/lens)*100)>current_percent: 18             print('#',end='',flush=True) 19             current_percent=int((received_size/lens)*100) 20         new_size=yield 21         received_size+=new_size 22  23  24 client=socket.socket() 25 client.connect(('localhost',9000)) 26 while True: 27     data_d=user_pwd(client) 28     if data_d['tag']:#运行#用户名登陆成功 29         while True: 30             print('''=====指令提示==== 31             查看目录文件: ls 32             下载文件: get 文件名 或 文件编号  如: get test.txt  或  get 1 33             上传方件: put 路径/文件名 如 put e:/test.txt 34             退出:exit 35             ''') 36             cho=input('指令 >>:').strip() 37             if len(cho)==0:continue 38             if cho=='exit':exit()#退出指令 39             cmd_list=cho.split() 40             if cmd_list[0]=='put':#如果等于下载指令 41                 if len(cmd_list)==1: 42                     print('没有输入相关文件名') 43                     continue 44                 filename=cmd_list[1] 45                 if os.path.isfile(filename):#如果文件存在 46                     file_obj=open(filename,"rb")#打开文件 47                     name=file_obj.name.split('/')[-1]#文件名 48                     #name=filename.split("\\")[-1]#文件名 49                     sez=os.path.getsize(filename)#获取文件大小 50                     data_header={ 51                         "action":"put", 52                         "filename":name, 53                         "size":sez 54                     } 55                     client.send(json.dumps(data_header).encode())#用json 序列化后,发送相关 信息 56  57                     print("文件[%s]发送中...."%data_header["filename"]) 58                     for line in file_obj: 59                         client.send(line) 60                     else: 61                         print("文件[%s]发送完毕!"%data_header["filename"]) 62                 else: 63                     print('该文件不存在') 64                     continue 65             elif cmd_list[0]=='get':#如查等 于上传指令 66                 if len(cmd_list)==1: 67                     print('没有输入相关文件名') 68                     continue 69                 filename=cmd_list[1] 70                 print(filename) 71                 data_header={ 72                         "action":"get", 73                         "filename":filename, 74                         "size":'' 75                     } 76                 client.send(json.dumps(data_header).encode())#用json 序列化后,发送相关 信息 77                 datas=client.recv(4096)#接收数据 指令 78                 data_l= json.loads(datas.decode())#反序列 79                 if  not data_l['filename']: 80                     print('文件不存在') 81                     continue 82                 file_dir=config.USER_DIR+data_l["filename"] 83                 file_obj=open(file_dir,'wb')#打开新建 这个文件 84                 rece_size=0#定义 文件大小值 85                 prten=show_process(data_l["size"]) 86                 prten.__next__() 87                 while rece_size<data_l["size"]:#小于接收的文件大小时, 88                     recv_data=client.recv(4096) 89                     file_obj.write(recv_data)#写入文件 90                     rece_size+=len(recv_data)#增加文件大小计算 91                     try: 92                         prten.send(len(recv_data)) 93                     except StopIteration as e: 94                         print(&#39;100%&#39;) 95  96                 else: 97                     print("文件[%s]接收完毕!"%data_l["filename"]) 98                     file_obj.flush() 99                     file_obj.close()#关闭文件100             elif cmd_list[0]==&#39;ls&#39;:#查看目录文件101                 data_header={102                         "action":"ls",103                         "filename":&#39;&#39;,104                         "size":&#39;&#39;105                     }106                 client.send(json.dumps(data_header).encode())#用json 序列化后,发送相关 信息107                 datas=client.recv(4096)#接收数据 指令108                 data_l= json.loads(datas.decode())#反序列109                 for k,v in enumerate(data_l):110                     print(&#39;编号: %s  文件名:%s&#39;%(k,v))111 112     else:113         print(data_d[&#39;mag&#39;])
登入後複製
View Code

cfg/

config.py

 1 #!usr/bin/env python 2 #-*-coding:utf-8-*- 3 # Author calmyan 4  5 import os ,sys 6 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量 7 sys.path.append(BASE_DIR)#增加环境变量 8  9 10 USER_DIR=BASE_DIR+&#39;\home\\&#39;#定义用户目录文件路径变量
登入後複製

core/

client_func.py

 1 #!usr/bin/env python 2 #-*-coding:utf-8-*- 3 # Author calmyan 4 import socket,os,json,sys 5 #用户名登陆函数 6 def user_pwd(client): 7     user_=input(&#39;请输入用户名:&#39;).strip() 8     pwd_=input(&#39;请输入密码:&#39;).strip() 9     data_header={10                 "action":"user",11                 "name":user_,12                 "pwd":pwd_13             }14     client.send(json.dumps(data_header).encode())#用json 序列化后,发送相关 信息15     data=client.recv(4096)#接收数据 指令16     data_s=json.loads(data.decode(&#39;utf-8&#39;))#反序列17     return data_s18 19 20 #进度条21 def show_process(lens):22     received_size=0#定义大小23     current_percent=0#当前大小百分比24     while received_size<lens:25         if int((received_size/lens)*100)>current_percent:26             print('#',end='',flush=True)27             current_percent=int((received_size/lens)*100)28         new_size=yield29         received_size+=new_size
登入後複製
View Code

 

以上是簡單FTP的實作詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1424
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

sublime怎麼運行代碼python sublime怎麼運行代碼python Apr 16, 2025 am 08:48 AM

在 Sublime Text 中運行 Python 代碼,需先安裝 Python 插件,再創建 .py 文件並編寫代碼,最後按 Ctrl B 運行代碼,輸出會在控制台中顯示。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Golang vs. Python:性能和可伸縮性 Golang vs. Python:性能和可伸縮性 Apr 19, 2025 am 12:18 AM

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

notepad 怎麼運行python notepad 怎麼運行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。

See all articles