• 转载别人的ftp,觉得目录结构不错,学习


    开发简单的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()
    复制代码

    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'#定义用户文件路径变量
    复制代码

    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('33[41;1m用户名或密码错误33[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
    复制代码

    客户端

    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('编号: %s  文件名:%s'%(k,v))
    111 
    112     else:
    113         print(data_d['mag'])
    复制代码

    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+'home\'#定义用户目录文件路径变量
    复制代码

    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('请输入用户名:').strip()
     8     pwd_=input('请输入密码:').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('utf-8'))#反序列
    17     return data_s
    18 
    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=yield
    29         received_size+=new_size
  • 相关阅读:
    JTree单击事件
    hibernate、easyui、struts2整合
    ubuntu中wifi显示被硬件禁用的解决方法
    idea导入svn项目
    Intellij IDEA常用配置详解
    HBase 写优化之 BulkLoad 实现数据快速入库
    Spark性能优化之道——解决Spark数据倾斜(Data Skew)的N种姿势
    avro序列化详细操作
    wordcount代码实现详解
    idea配置maven
  • 原文地址:https://www.cnblogs.com/xiaohuamao/p/7003830.html
Copyright © 2020-2023  润新知