您的位置:首页 > 编程语言 > Python开发

Python09作业思路及源码:高级FTP服务器开发(仅供参考)

2016-12-29 01:46 477 查看

高级FTP服务器开发

一,作业要求

高级FTP服务器开发

用户加密认证(完成)

多用户同时登陆(完成)

每个用户有不同家目录且只能访问自己的家目录(完成)

对用户进行磁盘配额,不同用户配额可不同(完成)

用户登录server后,可切换目录(完成)

查看当前目录下文件(完成)

上传下载文件保持文件一致性(完成)

传输过程中实现进度条(完成)

可以创建或删除目录及文件(完成)

支持断点续传(未做)

二,程序文件清单



Folder目录:用户文件目录

bin目录:程序启动文件目录

conf目录:用户配置文件目录

core目录:程序核心代码目录

log目录:程序日志文件目录

三,程序流程简图



四,程序测试样图

创建账户



用户登录



基本操作









五,核心源码清单

客户端核心源码

1 #!usr/bin/env python
2 # -*- coding:utf-8 -*-
3 # auther:Mr.chen
4 # 描述:
5
6 import socket,os
7 import time,json
8
9
10 DIR = os.path.dirname(os.path.abspath(__file__))
11 DIR = DIR.replace('core','Folder/')
12 HOST = 'localhost'
13 PORT = 8888
14
15
16
17
18 def ls_Method(s):
19     s.send("Begin!")
20     data = ''
21     while True:
22         buffer = s.recv(1024)
23         if buffer == 'Exit!':
24             break
25         if not buffer:
26             print ("服务器传输错误!")
27             return
28         data += buffer
29     print (data)
30
31
32 def put_Method(s,action,filename):
33     if os.path.exists(DIR+filename) and os.path.isdir(DIR+filename) == False:
34         with open(DIR+filename,'r') as f:
35             data = f.read()
36         data_size = len(data)
37         s.send(str(data_size))
38         if s.recv(1024) == 'OK!':
39             s.send(filename)
40             if s.recv(1024) == 'OK!':
41                 print ("文件开始上传,请稍后...")
42                 with open(DIR+filename,'r') as f:
43                     Num = None
44                     data = ''
45                     while True:
46                         buffer = f.read(1024)
47                         if not buffer:
48                             s.send("Exit!")
49                             break
50                         s.send(buffer)
51                         data += buffer
52                         Num = download_Progress(data_size, len(data), Num)
53                 if s.recv(1024) == 'OK!':
54                     print ("上传成功!磁盘配额剩余{0}M".format(s.recv(1024)))
55                 else:
56                     print ("文件传输有损,请重新上传!")
57             else:
58                 print ("不能上传!服务器上已有重名的文件")
59         else:
60             print ("磁盘配额已满,请清理磁盘空间!")
61     else:
62         s.send("False!")
63         print ("上传失败,没有这个文件或目标是个文件夹")
64
65
66 def get_Method(s,action,filename):
67     s.send(filename)
68     print ("正在下载,请等待...")
69     data = ''
70     data_size = s.recv(1024)
71     if data_size == "Flase!":
72         print ("下载失败!服务器没有找到或目标是个文件夹")
73         return
74     data_size = int(data_size)
75     Num = None
76     while True:
77         buffer = s.recv(1024)
78         if not buffer :
79             print ("文件损坏,请重新下载!")
80             break
81         data += buffer
82         Num = download_Progress(data_size,len(data),Num)
83         if data_size == len(data):
84             with open(DIR + filename, 'w') as f:
85                 f.write(data)
86                 print ("下载成功!")
87                 break
88
89
90 def cd_Method(s,action,filename):
91     s.send(filename)
92     re = s.recv(1024)
93     if re == 'OK!':
94         print ("命令执行成功!")
95     elif re == 'NULL!':
96         print ("已到根目录,不能继续返回!")
97     else:
98         print ("目录没有找到!")
99
100
101 def mkdir_Method(s,action,filename):
102     s.send(filename)
103     if s.recv(1024) == 'OK!':
104         print ("目录创建成功!")
105     else:
106         print ("已有同名目录或文件!")
107
108
109 def rm_Method(s,action,filename):
110     s.send(filename)
111     re = s.recv(1024)
112     if re == "OK!":
113         print ("删除成功!磁盘配额剩余{0}M".format(s.recv(1024)))
114     elif re == "DIR!":
115         while True:
116             decide = raw_input("您选择的目标是个文件夹,是否递归删除(y/n):")
117             if decide == 'y':
118                 s.send("OK!")
119                 re = s.recv(1024)
120                 if re == "OK!":
121                     print ("删除成功,磁盘配额剩余{0}M".format(s.recv(1024)))
122                     break
123                 else:
124                     print ("删除失败,原因未知!")
125                     break
126             elif decide == 'n':
127                 s.send("False!")
128                 break
129             else:
130                 print ("您的输入有误!")
131     else:
132         print ("没有这个文件")
133
134
135 def download_Progress(size_total,size,Num):
136     num = size * 100 / size_total
137     if Num == None:
138         # print (str(num)+"%")
139         print "\r%d" % num,
140         time.sleep(0.01)
141         return num
142     elif num == Num:
143         return num
144     else:
145         print "\r%d" % num,
146         time.sleep(0.01)
147         return num
148
149
150
151
152 def MD5(password):
153     """
154     加密函数
155     :param password:
156     :return:
157     """
158     import hashlib
159     return hashlib.md5(password).hexdigest()
160
161
162 def File_transfer(s):
163     """
164     用户指令函数
165     :param s:
166     :return:
167     """
168
169     while True:
170         command = raw_input("请输入你想执行的命令>>")
171         if not command:
172             continue
173         if command.lower().strip() == 'help':
174             text = """
175                     请用'put'+'空格'+'文件名'的格式上传文件
176                     请用'get'+'空格'+'文件名'的格式下载文件
177                     请用'cd'+'空格'+'目录名'的格式进入家目录下的子文件夹
178                     请用'cd'+'空格'+'..'的格式返回上级目录
179                     请用'mkdir'+'空格'+'目录名'的格式进入家目录的文件夹
180                     请用'rm'+'空格'+'文件名/目录名'的格式删除家目录下的文件
181                     输入'ls'查看用户服务器家目录
182             """
183             print (text)
184             continue
185         try:
186             action,filename = command.strip().split()
187             action = action.lower()
188         except:
189             if command.lower().strip() == 'ls':
190                 s.send('ls')
191                 print ("正在查询,请稍后...")
192                 if s.recv(1024) == 'OK!':
193                     ls_Method(s)
194             else:
195                 print ("您的输入有误!输入help查看帮助文档")
196                 continue
197         else:
198             s.send(action)
199             if s.recv(1024) == 'OK!':
200                 eval(action+'_Method')(s,action,filename)
201             else:
202                 print ("您的输入有误!输入help查看帮助文档")
203
204
205 def Login(s):
206     """
207     用户登录
208     :param s:
209     :return:
210     """
211     while True:
212         name = raw_input("请输入你的登陆名:").strip()
213         password = raw_input("请输入你的密码:").strip()
214         if not name or not password:
215             print ("用户名和密码不能为空!")
216             continue
217         password = MD5(password)   #密码加密
218         data = [name,password]
219         s.send(json.dumps(data))
220         if s.recv(1024) == 'OK!':
221             print ("用户登陆成功!")
222             File_transfer(s)
223         else:
224             print ("用户登陆失败!")
225
226
227 def Main():
228     """
229     用户登陆
230     :param s:
231     :param log:
232     :return:
233     """
234     s = socket.socket()
235     try:
236         s.connect((HOST, PORT))
237         s.send("Ready!")
238
239         data = s.recv(1024)  #接收服务器欢迎信息
240         if not data:
241             print ("服务器异常!")
242         else:
243             print (data)
244             Login(s)
245     except Exception,e:
246         print "服务器连接不上....", e
247     finally:
248         s.close()
249
250
251 if __name__ == "__main__":
252     Main()


服务器端核心源码

1 #!usr/bin/env python
2 # -*- coding:utf-8 -*-
3 # auther:Mr.chen
4 # 描述:
5
6 import SocketServer
7 import os,time,sys,json
8 import admin_configure
9 DIR = os.path.dirname(os.path.abspath(__file__))
10 DIR = DIR.replace('core','Folder/')
11
12
13
14 class Myserver(SocketServer.BaseRequestHandler):
15
16     def __init__(self,request,client_address,server):
17         SocketServer.BaseRequestHandler.__init__(self,request,client_address,server)
18         self.Name = ''          #用户名
19         self.Password = ''      #用户密码
20         self.Quota = ''         #用户磁盘配额
21         self.Home_path = ''     #用户家目录路径
22         self.Current_path = ''  #用户当前路径
23         self.DIR = []           #用户进入过的子目录列表
24
25
26
27     def ls_Method(self):
28         data = self.request.recv(1024)
29         if data == 'Begin!':
30             data = os.popen('ls'+' '+self.Current_path).read()
31             self.request.sendall(data)
32             time.sleep(0.5)
33             self.request.send("Exit!")
34
35
36     def put_Method(self):
37         data_size = self.request.recv(1024)
38         if data_size == 'False!':
39             return
40         if int(self.Quota) >= int(data_size):
41             self.request.send("OK!")
42             filename = self.request.recv(1024)
43             if os.path.exists(self.Current_path+filename) == False:
44                 self.request.send("OK!")
45                 data = ''
46                 while True:
47                     buffer = self.request.recv(1024)
48                     if buffer == 'Exit!':
49                         break
50                     if not buffer:
51                         break
52                     data += buffer
53                 self.Quota = str(int(self.Quota) - len(data))
54                 dict = admin_configure.config_read(self.Name)
55                 dict['Quota'] = self.Quota
56                 admin_configure.config_write(dict)
57                 with open(self.Current_path+filename,'w') as f:
58                     f.write(data)
59                 if len(data) == int(data_size):
60                     self.request.send("OK!")
61                     time.sleep(0.25)
62                     Quota = str(float(self.Quota)/1000000)
63                     self.request.send(Quota)
64                 else:
65                     self.request.send("Flase!")
66             else:
67                 self.request.send("False!")
68         else:
69             self.request.send("Flase!")
70
71
72
73     def get_Method(self):
74         filename = self.request.recv(1024)
75         if os.path.exists(self.Current_path+filename) and os.path.isdir(self.Current_path+filename) == False:
76             with open(self.Current_path+filename,'r') as f:
77                 data = f.read()
78                 self.request.send(str(len(data)))
79                 time.sleep(0.5)
80                 self.request.sendall(data)
81         else:
82             self.request.send("Flase!")
83
84
85
86
87
88     def cd_Method(self):
89         filename = self.request.recv(1024)
90         if filename == '..':
91             if len(self.DIR) == 0:
92                 self.request.send("NULL!")
93                 return
94             else:
95                 # self.Current_path = self.Current_path.replace('/'+self.DIR[0]+'/','/')
96                 list = self.Current_path.split('/')
97                 del  list[0]
98                 del list[len(list) - 1]
99                 del list[len(list) - 1]
100                 str = '/'
101                 for i in range(len(list)):
102                     str = str + list[i] + '/'
103                 self.Current_path = str
104                 del self.DIR[0]
105                 self.request.send("OK!")
106         elif os.path.isdir(self.Current_path+filename):
107                 self.Current_path = self.Current_path + filename + '/'
108                 self.DIR.insert(0,filename)
109                 self.request.send("OK!")
110         else:
111             self.request.send("False!")
112
113
114     def mkdir_Method(self):
115         filename = self.request.recv(1024)
116         if os.path.exists(self.Current_path+filename):
117             self.request.send("False!")
118         else:
119             os.system("mkdir -p " + self.Current_path + filename)
120             if os.path.exists(self.Current_path + filename):
121                 self.request.send("OK!")
122             else:
123                 self.request.send("False!")
124
125     def rm_Method(self):
126         filename = self.request.recv(1024)
127         if os.path.exists(self.Current_path+filename):
128             if os.path.isdir(self.Current_path+filename):
129                 self.request.send("DIR!")
130                 if self.request.recv(1024) == "OK!":
131                     data = os.popen('du'+' '+ '-sk' + ' ' + self.Current_path+filename).read()
132                     data_size,file = data.strip().split()
133                     os.system("rm -rf " + self.Current_path + filename)
134                     self.Quota = str(int(self.Quota) + int(data_size))
135                     dict = admin_configure.config_read(self.Name)
136                     dict['Quota'] = self.Quota
137                     admin_configure.config_write(dict)
138                     self.request.send("OK!")
139                     time.sleep(0.25)
140                     Quota = str(float(self.Quota) / 1000000)
141                     self.request.send(Quota)
142
143                 else:
144                     return
145             else:
146                 with open(self.Current_path+filename,'r') as f:
147                     data = f.read()
148                 os.system("rm -f " + self.Current_path + filename)
149                 self.Quota = str(int(self.Quota) + len(data))
150                 dict = admin_configure.config_read(self.Name)
151                 dict['Quota'] = self.Quota
152                 admin_configure.config_write(dict)
153                 self.request.send("OK!")
154                 time.sleep(0.25)
155                 Quota = str(float(self.Quota) / 1000000)
156                 self.request.send(Quota)
157         else:
158             self.request.send("False!")
159
160     def Login_Method(self,data):
161         re = admin_configure.config_read(data[0])
162         if re == None:
163             return False
164         else:
165             if re['Password'] == data[1]:
166                 self.Name = re['Name']
167                 self.Password = re['Password']
168                 self.Quota = re['Quota']
169                 self.Home_path = re['Home_path']
170                 self.Current_path = re['Current_path']
171                 self.DIR = []
172                 return True
173             else:
174                 return False
175
176
177
178
179
180
181
182     def handle(self):
183         conn = self.request
184         conn.recv(1024)
185         print ("收到来自{0}的客户端连接...".format(self.client_address[0]))
186         conn.send("欢迎你!")
187         try:
188             while True:
189                 print ("正在等待客户端发送验证信息!")
190                 self.data = json.loads(conn.recv(1024))
191                 # if not self.data:
192                 #     break
193                 if not self.data or type(self.data) != list:
194                     conn.send("false!")
195                 else:
196                     re = self.Login_Method(self.data)
197                     if re == True:
198                         print ("客户端认证成功!")
199                         conn.send("OK!")
200                         while True:
201                             print ("正在等待客户端响应...")
202                             data = conn.recv(1024)
203                             # if not data:
204                             #     break
205                             if hasattr(self,data +'_Method'):
206                                 conn.send("OK!")
207                                 getattr(self,data +'_Method')()
208                             else:
209                                 conn.send("flase")
210
211                     else:
212                         conn.send("flase!")
213         except Exception,e:
214             print "客户端失去连接!",e
215
216 def Main():
217     HOST = 'localhost'
218     PORT = 8888
219     s = SocketServer.ThreadingTCPServer((HOST, PORT), Myserver)
220     print ("正在等待客户端连接...")
221     s.serve_forever()
222
223
224
225 if __name__ == "__main__":
226     Main()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: