python第四十一天---作業:簡單FTP

来源:http://www.cnblogs.com/uge3/archive/2017/06/12/6993604.html
-Advertisement-
Play Games

作業要示: 開發簡單的FTP:1. 用戶登陸2. 上傳/下載文件3. 不同用戶家目錄不同4. 查看當前目錄下文件5. 充分使用面向對象知識 REDMAE 服務端 servers/ bin/ registration.py 1 #!usr/bin/env python 2 #-*-coding:utf ...


 

作業要示:

開發簡單的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__.py
12 |      |- - -bin/#啟用目錄
13 |      |       |- - - __init__.py
14 |      |       |- - -socket_client.py#客戶端啟動
15 |      |
16 |      |- - -cfg/#配置文件目錄
17 |      |       |- - - __init__.py
18 |      |       |- - -config.py#配置文件
19 |      |
20 |      |- - -core/#主要程式目錄
21 |      |       |- - - __init__.py
22 |      |       |- - -client_func.py#主要函數
23 |      |
24 |      |- - -home/#客戶端下載文件目錄
25 |
26 |- - -servers/#server程式主目錄
27 |      |- - -__init__.py
28 |      |- - -bin/#啟用目錄
29 |      |       |- - - __init__.py
30 |      |       |- - -registration.py#用戶註冊
31 |      |       |- - -socket_server.py#服務端啟動
32 
33 |      |
34 |      |- - -cfg/#配置文件目錄
35 |      |       |- - - __init__.py
36 |      |       |- - -config.py#配置文件
37 |      |
38 |      |- - -core/#主要程式目錄
39 |      |       |- - - __init__.py
40 |      |       |- - -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         continue
16     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                 continue
25             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_func
10 s=socket.socket()#定義
11 s.bind(('localhost',9000))#綁定要監聽的 埠
12 s.listen(5)#對列5
13 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     @staticmethod
110     def login(name,pas,conn):#用戶檢測 函數
111         try:
112             if open_file_list(name,pas):
113                 tag=True
114                 error=''
115                 datas={'user':name}
116                 data={'mag':'用戶認證通過','tag':True}
117                 print(json.dumps(data).encode())
118                 conn.send(json.dumps(data).encode())
119             else:
120                 raise Exception('\033[41;1m用戶名或密碼錯誤\033[0m' %name)
121         except Exception as e:
122             tag=False
123             error=str(e)
124             datas=''
125             data={'mag':'用戶或密碼錯誤','tag':False}
126             print('發送數據%s'%data)
127             conn.send(json.dumps(data).encode())
128         return {'tag':tag,'error':error,'data':datas}
129 
130 #監聽函數
131 def listen_func(s):
132     while True:
133         conn,client_addr=s.accept()#埠監聽中....返回兩個值 ,聯接編號對象 , ip
134         print('獲取到新連接:',client_addr)
135         while True:
136             data=conn.recv(4096)#接收數據 指令
137             print('接收的數據:',data)
138             data= json.loads(data.decode())#反序列
139             if len(data)==0:
140                 break
141             if data['action']=='user':#如果是用戶名,進行認證\
142                 serv=socket_server(data,conn)
143                 ret=serv.ret_l()
144             if ret['tag']:
145                 pass
146             else:
147                 continue
148 
149             print(data)
150             if data['action']=="put":#如果接收的字典中是put,就是進行接收
151                 serv=socket_server(data,conn)
152                 serv.put_file(serv.open_f(ret))#調對象方法
153             elif data['action']=='get':#下載
154                 serv=socket_server(data,conn)#實例化
155                 serv.send_file(serv.open_f(ret))#調 用方法
156             elif data['action']=='ls':#查看
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('100%')
 95 
 96                 else:
 97                     print("文件[%s]接收完畢!"%data_l["filename"])
 98                     file_obj.flush()
 99                     file_obj.close()#關閉文件
100             elif cmd_list[0]=='ls':#查看目錄文件
101                 data_header={
102                         "action":"ls",
103                         "filename":'',
104                         "size":''
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
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 鍵盤錄入(Java): 1.導包 格式 import java.util.Scanner; 位置 在class上面 2.創建鍵盤錄入對象 格式 Scanner sc = new Scanner(System.in); 3.通過對象獲取數據 格式 int x = sc.nextInt(); impor ...
  • 最近看了看JavaWeb的書籍,才感覺到大二時候學的JavaWeb才僅僅只是個入門。最尷尬的當初還沒咋學一直在看.NET,現在看起來JavaWeb,各種框架各種頭疼啊。看了幾個例子之後覺得,還是自己動手做個項目試試。邊做邊學才能學的快一點。做的時候用博客園記錄下過程,省得以後忘。之所以選圖書館管理系 ...
  • 本文是作者在學習了軟體工程(C編碼實踐篇)課程後的學習總結性質的文章 希望能通過自己的一些理解和經驗幫助大家更好地理解軟體工程的有關內容。。 學生 戢祥 課程地址《軟體工程(C編碼實踐篇)》MOOC課程http://mooc.study.163.com/course/USTC-1000002006 ...
  • 為瞭解決用一個命令(巨集)給方法,類,js方法添加註釋,經過幾天的研究.終於得到結果了. 實現的效果如下: 給Java中的method添加方法: 給 Java class 添加註釋: 給js 的方法添加註釋 現在把答案公佈如下 Abbreviation: Template text(註1): Edit ...
  • python ...
  • 一、ServerSocketChannel Java NIO中的 ServerSocketChannel 是一個可以監聽新進來的TCP連接的通道, 就像標準IO中的ServerSocket一樣。ServerSocketChannel類在 java.nio.channels包中。 打開 ServerS ...
  • 在spider中最後一個函數返回item時會scrapy會調用pipeline裡面的 ...
  • scrapy stratproject projectname ##創建一個項目 scrapy genspider myspidername fider ##創建一個spider文件 scrapy crawl spidername ## 執行一個spider程式 scrapy shell url # ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...