zoukankan      html  css  js  c++  java
  • python第四十一天---作业:简单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()
    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('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
    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('编号: %s  文件名:%s'%(k,v))
    111 
    112     else:
    113         print(data_d['mag'])
    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+'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
    View Code

    您的资助是我最大的动力!
    金额随意,欢迎来赏!

    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的推荐按钮。
    如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的关注我

    如果,想给予我更多的鼓励,求打

    因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【莫柔落切】!

    联系或打赏博主【莫柔落切】!https://home.cnblogs.com/u/uge3/

  • 相关阅读:
    Could A New Linux Base For Tablets/Smartphones Succeed In 2017?
    使用libhybris,glibc和bionic共存时的TLS冲突的问题
    6 Open Source Mobile OS Alternatives To Android in 2018
    Using MultiROM
    GPU drivers are written by the GPU IP vendors and they only provide Android drivers
    Jolla Brings Wayland Atop Android GPU Drivers
    How to Use Libhybris and Android GPU Libraries with Mer (Linux) on the Cubieboard
    闲聊Libhybris
    【ARM-Linux开发】wayland和weston的介绍
    Wayland and X.org problem : Why not following the Android Solution ?
  • 原文地址:https://www.cnblogs.com/uge3/p/6993604.html
Copyright © 2011-2022 走看看