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


    高级FTP服务器开发

    一,作业要求

    高级FTP服务器开发

    1. 用户加密认证(完成)
    2. 多用户同时登陆(完成)
    3. 每个用户有不同家目录且只能访问自己的家目录(完成)
    4. 对用户进行磁盘配额,不同用户配额可不同(完成)
    5. 用户登录server后,可切换目录(完成)
    6. 查看当前目录下文件(完成)
    7. 上传下载文件保持文件一致性(完成)
    8. 传输过程中实现进度条(完成)
    9. 可以创建或删除目录及文件(完成)
    10. 支持断点续传(未做)

    二,程序文件清单

    • 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 "
    %d" % num,
    140         time.sleep(0.01)
    141         return num
    142     elif num == Num:
    143         return num
    144     else:
    145         print "
    %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()
  • 相关阅读:
    Chapter 14_2 全局变量声明
    chapter 14_1 环境
    chapter 13_4 跟踪table的访问
    Linq to Entity 和 Linq to Object 异同
    ADO.net实体类操作
    XML
    JavaScript
    CSS样式表
    HTML
    java 反射
  • 原文地址:https://www.cnblogs.com/chensiqiqi/p/6231486.html
Copyright © 2020-2023  润新知