作业要示:

开发简单的FTP:
1. 用户登陆
2. 上传/下载文件
3. 不同用户家目录不同
4. 查看当前目录下文件
5. 充分使用面向对象知识

REDMAE

 用户登陆

 1、查看用户目录文件
2、上传文件,
3、下载方件
4、退出 程序结构:
socket_server_client/#程序目录
|- - -clients/#client程序主目录
| |- - -__init__.py
| |- - -bin/#启用目录
| | |- - - __init__.py
| | |- - -socket_client.py#客户端启动
| |
| |- - -cfg/#配置文件目录
| | |- - - __init__.py
| | |- - -config.py#配置文件
| |
| |- - -core/#主要程序目录
| | |- - - __init__.py
| | |- - -client_func.py#主要函数
| |
| |- - -home/#客户端下载文件目录
|
|- - -servers/#server程序主目录
| |- - -__init__.py
| |- - -bin/#启用目录
| | |- - - __init__.py
| | |- - -registration.py#用户注册
| | |- - -socket_server.py#服务端启动 | |
| |- - -cfg/#配置文件目录
| | |- - - __init__.py
| | |- - -config.py#配置文件
| |
| |- - -core/#主要程序目录
| | |- - - __init__.py
| | |- - -server_classc.py#主要函数
| |
| |- - -db/#用户上传文件主目录
| |- - -user_file/#用户上传目录
| |- - -user_names#注册用户文件
|

服务端

servers/

    bin/

registration.py

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
import socket,os,json,sys,pickle BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量
sys.path.append(BASE_DIR)#增加环境变量
from cfg import config
print('用户注册'.center(60,'='))
while True:
user_=input('请输入您要注册的用户名:').strip()
user_dir=os.path.join(config.USER_DIR,user_)#拼接用户目录路径
if os.path.isdir(user_dir):# 判断一个目录是否存在
print('用户已经存在请重输!')
continue
else:
pwd_=input('请输入密码:').strip()
pwd_two=input('请确认密码:').strip()
if pwd_==pwd_two:
try:
os.mkdir(user_dir)#创建目录
except Exception as e:
print(e)
continue
finally:
file_dir=user_dir+'\\user'#用户目录下的用户名文件
if not os.path.isfile(config.USER_FILE):
with open(config.USER_FILE,'w',encoding='utf-8') as f:
f.write('{}')
with open(config.USER_FILE,'r+',encoding='utf-8') as f:
data=eval(f.readline())
data[user_]=pwd_
f.seek(0)
f.write(str(data))
print('用户[%s]注册成功!'%user_)
exit()

socket_server.py

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
import socket,os,json
import sys
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量
sys.path.append(BASE_DIR)#增加环境变量 from core.server_class import listen_func
s=socket.socket()#定义
s.bind(('localhost',9000))#绑定要监听的 端口
s.listen(5)#对列5
print('正在监听中')
listen_func(s)

cfg/

config.py

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
import os ,sys
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量
sys.path.append(BASE_DIR)#增加环境变量 USER_DIR=BASE_DIR+'\db\\user_file\\'#定义用户目录文件路径变量 USER_FILE=BASE_DIR+'\db\\user_names'#定义用户文件路径变量

core/

server_class.py

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
import socket,os,json,sys,pickle BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量
sys.path.append(BASE_DIR)#增加环境变量 from cfg import config #用户名检测函数
def open_file_list(name,pas):#传入当前类
with open(config.USER_FILE,'r',encoding='utf-8') as f:
data=eval(f.readline())
if name in data and pas==data[name]:
return True
else:
return False #连接类
class socket_server(object):
'''连接类'''
file_path=config.USER_DIR#用户路经变量
def __init__(self,data,conn):#传入用户名,密码
self.DATA=data
self.conn=conn def show_process(self,lens):
received_size=0#定义大小
current_percent=0#当前大小百分比
while received_size<lens:
if int((received_size/lens)*100)>current_percent:
print('#',end='',flush=True)
current_percent=int((received_size/lens)*100)
new_size=yield
received_size+=new_size def ret_l(self):
ret=socket_server.login(self.DATA["name"],self.DATA['pwd'],self.conn)#用户名检测
return ret
def open_f(self,ret):#打开目录
file_dir=os.path.join(socket_server.file_path,ret['data']['user'])#用户目录
file_name=os.listdir(file_dir)#目录文件列表
f=file_dir+self.DATA['filename']##上传的文件名
return file_dir,file_name,f#返回 def ls_file(self,data):#查看文件
self.conn.send(json.dumps(data[1]).encode()) def send_file(self,data): if self.DATA['filename'] in data[1]:
f=data[0]+'/'+self.DATA['filename']
file_obj=open(f,"rb")#打开文件
name=file_obj.name.split('/')[-1]#文件名
sez=os.path.getsize(f)#获取文件大小
print(sez)
data_header={
"action":"put",
"filename":name,
"size":sez
}
self.conn.send(json.dumps(data_header).encode())#用json 序列化后,发送相关 信息
for line in file_obj:
self.conn.send(line)#发送数据 elif self.DATA['filename'].isdigit():
num=int(self.DATA['filename'])#转为数字
try:
f=data[0]+'/'+data[1][num]#
file_obj=open(f,"rb")#打开文件
name=file_obj.name.split('/')[-1]#文件名
sez=os.path.getsize(f)#获取文件大小
print(sez)
data_header={
"action":"put",
"filename":name,
"size":sez
}
self.conn.send(json.dumps(data_header).encode())#用json 序列化后,发送相关 信息
for line in file_obj:
self.conn.send(line)#发送数据
self.conn.send(json.dumps(f).encode())#发送文件
except Exception as e:
data={'filename':False}
self.conn.send(json.dumps(data).encode())
else:
data={'filename':False}
self.conn.send(json.dumps(data).encode())
def put_file(self,data):#上传文件
file_obj=open(data[2],'wb')#打开新建 这个文件
rece_size=0#定义 文件大小值
#prten=socket_server.show_process(self.DATA["size"])
#prten.__next__()
while rece_size<self.DATA["size"]:#小于接收的文件大小时,
recv_data=self.conn.recv(4096)
file_obj.write(recv_data)#写入文件
rece_size+=len(recv_data)#增加文件大小计算 else:
print("文件[%s]接收完毕!"%self.DATA["filename"])
file_obj.flush()
file_obj.close()#关闭文件 @staticmethod
def login(name,pas,conn):#用户检测 函数
try:
if open_file_list(name,pas):
tag=True
error=''
datas={'user':name}
data={'mag':'用户认证通过','tag':True}
print(json.dumps(data).encode())
conn.send(json.dumps(data).encode())
else:
raise Exception('\033[41;1m用户名或密码错误\033[0m' %name)
except Exception as e:
tag=False
error=str(e)
datas=''
data={'mag':'用户或密码错误','tag':False}
print('发送数据%s'%data)
conn.send(json.dumps(data).encode())
return {'tag':tag,'error':error,'data':datas} #监听函数
def listen_func(s):
while True:
conn,client_addr=s.accept()#端口监听中....返回两个值 ,联接编号对象 , ip
print('获取到新连接:',client_addr)
while True:
data=conn.recv(4096)#接收数据 指令
print('接收的数据:',data)
data= json.loads(data.decode())#反序列
if len(data)==0:
break
if data['action']=='user':#如果是用户名,进行认证\
serv=socket_server(data,conn)
ret=serv.ret_l()
if ret['tag']:
pass
else:
continue print(data)
if data['action']=="put":#如果接收的字典中是put,就是进行接收
serv=socket_server(data,conn)
serv.put_file(serv.open_f(ret))#调对象方法
elif data['action']=='get':#下载
serv=socket_server(data,conn)#实例化
serv.send_file(serv.open_f(ret))#调 用方法
elif data['action']=='ls':#查看
serv=socket_server(data,conn)
serv.ls_file(serv.open_f(ret))
continue

客户端

clients/

bin/

socket_client.py

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan import socket,os,json,sys
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量
sys.path.append(BASE_DIR)#增加环境变量
from core.client_func import user_pwd
#from core.client_func import show_process
from cfg import config #进度条
def show_process(lens):
received_size=0#定义大小
current_percent=0#当前大小百分比
while received_size<lens:
if int((received_size/lens)*100)>current_percent:
print('#',end='',flush=True)
current_percent=int((received_size/lens)*100)
new_size=yield
received_size+=new_size client=socket.socket()
client.connect(('localhost',9000))
while True:
data_d=user_pwd(client)
if data_d['tag']:#运行#用户名登陆成功
while True:
print('''=====指令提示====
查看目录文件: ls
下载文件: get 文件名 或 文件编号 如: get test.txt 或 get 1
上传方件: put 路径/文件名 如 put e:/test.txt
退出:exit
''')
cho=input('指令 >>:').strip()
if len(cho)==0:continue
if cho=='exit':exit()#退出指令
cmd_list=cho.split()
if cmd_list[0]=='put':#如果等于下载指令
if len(cmd_list)==1:
print('没有输入相关文件名')
continue
filename=cmd_list[1]
if os.path.isfile(filename):#如果文件存在
file_obj=open(filename,"rb")#打开文件
name=file_obj.name.split('/')[-1]#文件名
#name=filename.split("\\")[-1]#文件名
sez=os.path.getsize(filename)#获取文件大小
data_header={
"action":"put",
"filename":name,
"size":sez
}
client.send(json.dumps(data_header).encode())#用json 序列化后,发送相关 信息 print("文件[%s]发送中...."%data_header["filename"])
for line in file_obj:
client.send(line)
else:
print("文件[%s]发送完毕!"%data_header["filename"])
else:
print('该文件不存在')
continue
elif cmd_list[0]=='get':#如查等 于上传指令
if len(cmd_list)==1:
print('没有输入相关文件名')
continue
filename=cmd_list[1]
print(filename)
data_header={
"action":"get",
"filename":filename,
"size":''
}
client.send(json.dumps(data_header).encode())#用json 序列化后,发送相关 信息
datas=client.recv(4096)#接收数据 指令
data_l= json.loads(datas.decode())#反序列
if not data_l['filename']:
print('文件不存在')
continue
file_dir=config.USER_DIR+data_l["filename"]
file_obj=open(file_dir,'wb')#打开新建 这个文件
rece_size=0#定义 文件大小值
prten=show_process(data_l["size"])
prten.__next__()
while rece_size<data_l["size"]:#小于接收的文件大小时,
recv_data=client.recv(4096)
file_obj.write(recv_data)#写入文件
rece_size+=len(recv_data)#增加文件大小计算
try:
prten.send(len(recv_data))
except StopIteration as e:
print('100%') else:
print("文件[%s]接收完毕!"%data_l["filename"])
file_obj.flush()
file_obj.close()#关闭文件
elif cmd_list[0]=='ls':#查看目录文件
data_header={
"action":"ls",
"filename":'',
"size":''
}
client.send(json.dumps(data_header).encode())#用json 序列化后,发送相关 信息
datas=client.recv(4096)#接收数据 指令
data_l= json.loads(datas.decode())#反序列
for k,v in enumerate(data_l):
print('编号: %s 文件名:%s'%(k,v)) else:
print(data_d['mag'])

cfg/

config.py

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan import os ,sys
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量
sys.path.append(BASE_DIR)#增加环境变量 USER_DIR=BASE_DIR+'\home\\'#定义用户目录文件路径变量

core/

client_func.py

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
import socket,os,json,sys
#用户名登陆函数
def user_pwd(client):
user_=input('请输入用户名:').strip()
pwd_=input('请输入密码:').strip()
data_header={
"action":"user",
"name":user_,
"pwd":pwd_
}
client.send(json.dumps(data_header).encode())#用json 序列化后,发送相关 信息
data=client.recv(4096)#接收数据 指令
data_s=json.loads(data.decode('utf-8'))#反序列
return data_s #进度条
def show_process(lens):
received_size=0#定义大小
current_percent=0#当前大小百分比
while received_size<lens:
if int((received_size/lens)*100)>current_percent:
print('#',end='',flush=True)
current_percent=int((received_size/lens)*100)
new_size=yield
received_size+=new_size

python第四十一天---作业:简单FTP的更多相关文章

  1. python作业简单FTP(第七周)

    作业需求: 1. 用户登陆 2. 上传/下载文件 3. 不同用户家目录不同 4. 查看当前目录下文件 5. 充分使用面向对象知识 思路分析: 1.用户登陆保存文件对比用户名密码. 2.上传用json序 ...

  2. 第七周作业——简单FTP

    开发简单的FTP: 1. 用户登陆 2. 上传/下载文件 3. 不同用户家目录不同 4. 查看当前目录下文件 5. 充分使用面向对象知识 1.目录结构zuoye-ftp├── chenliang #用 ...

  3. python作业高级FTP

    转载自:https://www.cnblogs.com/sean-yao/p/7882638.html 作业需求: 1. 用户加密认证 2. 多用户同时登陆 3. 每个用户有自己的家目录且只能访问自己 ...

  4. python作业高级FTP(第八周)

    作业需求: 1. 用户加密认证 2. 多用户同时登陆 3. 每个用户有自己的家目录且只能访问自己的家目录 4. 对用户进行磁盘配额.不同用户配额可不同 5. 用户可以登陆server后,可切换目录 6 ...

  5. 用python开发简单ftp程序

    根据alex老师视频开发的简单ftp程序,只能实现简单的get功能 ftp客户端程序: #!/usr/bin/env python #_*_ coding:utf-8 _*_ import socke ...

  6. 基于python复制蓝鲸作业平台

    前言 去年看武sir代码发布的视频无意中听到了蓝鲸平台但是一直没深究,前一段时间公司要搞一个代码发布平台,但是需求变化很多一直找不到一个很好的参考 模板,直到试用了一下蓝鲸作业平台发现“一切皆作业”的 ...

  7. Linux yum的配置 , python环境管理, nginx搭建简单学习

    Linux yum的配置 , python环境管理, nginx搭建简单学习 一丶配置yum的数据仓库 ### yum 工具, 方便,自行解决软件之间的依赖关系. # 配置yum源仓库 (可以使用,清 ...

  8. Python常用的库简单介绍一下

    Python常用的库简单介绍一下fuzzywuzzy ,字符串模糊匹配. esmre ,正则表达式的加速器. colorama 主要用来给文本添加各种颜色,并且非常简单易用. Prettytable ...

  9. python 多线程就这么简单(续)

    之前讲了多线程的一篇博客,感觉讲的意犹未尽,其实,多线程非常有意思.因为我们在使用电脑的过程中无时无刻都在多进程和多线程.我们可以接着之前的例子继续讲.请先看我的上一篇博客. python 多线程就这 ...

随机推荐

  1. oracle生成AWR报告方法

    2018-04-02 19:59:42 在10g 11g中AWR自动的每隔一小时进行一次数据采集并生成快照.下面是生成AWR报告的步骤: 1:使用oracle用户在数据库服务器上执行如下命令 sqlp ...

  2. 全网最详细的一个超级好用的命令行工具【Cmder】是什么?

    不多说,直接上干货! Cmder是什么? 一款Windows环境下非常简洁美观易用的cmd替代者,它支持了大部分的Linux命令.支持ssh连接linux,使用起来非常方便.比起cmd.powersh ...

  3. TCP/IP 笔记 - ICMPv4和ICMPv6 : Internet控制报文协议

    ICMP是一种面向无连接的协议,负责传递可能需要注意的差错和控制报文,差错指示通信网络是否存在错误(如目的主机无法到达.IP路由器无法正常传输数据包等.注意,路由器缓冲区溢出导致的丢包不包括在ICMP ...

  4. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(十七):登录验证码实现(Captcha)

    登录验证码 登录验证是一般系统都会有的功能,验证的方式也多种多样,比如输入式验证码,拖动式验证条,拖动式验证拼图等等. 我们这里先实现常规的输入验证码的方式,右边显示验证码图片,点击可刷新,左边输入验 ...

  5. redis 五种数据类型

    前言 前面学会了单机, 学会了集群, 但是redis咋用啊? 或者说, redis支持哪些数据类型呢? 常用的有五种: String , Hash, List, Set, zset(SortedSet ...

  6. leetcode — reverse-nodes-in-k-group

    /** * Source : https://oj.leetcode.com/problems/reverse-nodes-in-k-group/ * * Created by lverpeng on ...

  7. Jmeter JDBC Request 查询语句中有汉字查询结果为空的解决方法

    搜索接口我会校验返回值,查询JDBC Request 查询语句有中文字的时候查询会有问题. 解决方法很简单,在JDBC Connection Configuration的Database URL里加一 ...

  8. 检测到是移动端还是PC端进入页面,加载不同样式表现

    if(/AppleWebKit.*mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alc ...

  9. element split 将多个单号分隔

    const condeid = this.formData.WayBillCode; var item = ""; const codes = condeid.split(&quo ...

  10. AnyVal与AnyRef

    AnyRef 是所有引用类型的基类.除了值类型,所有类型都继承自AnyRef .   AnyVal AnyVal 所有值类型的基类, 它描述的是值,而不是代表一个对象. 它包括 9 个 AnyVal ...