开发简单的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('\033[41;1m用户名或密码错误\033[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

转载别人的ftp,觉得目录结构不错,学习的更多相关文章

  1. 【转载】Linux 文件系统的目录结构

    /bin 基础系统所需要的那些命令位于此目录,也是最小系统所需要的命令:比如 ls.cp.mkdir等命令:功能和/usr/bin类似,这个目录中的文件都是可执行的,普通用户都可以使用的命令.做为基础 ...

  2. 源代码目录结构--AngularJS学习笔记(一)

    最近开始接触AngularJS,确实是一个相当不错的东西,可以把很多东西简化掉.又对于其中的双向绑定等的实现很好奇,加之正在学习Javascript的东西,所以觉得从源代码这块开始深入学习Angula ...

  3. CentOS6.5菜鸟之旅:纯转载Linux目录结构

    来自:http://www.iteye.com/topic/1125162 使用linux也有一年多时间了  最近也是一直在维护网站系统主机  下面是linux目录结构说明 本人使用的是centos系 ...

  4. 使用递归方法实现,向FTP服务器上传整个目录结构、从FTP服务器下载整个目录到本地的功能

    我最近由于在做一个关于FTP文件上传和下载的功能时候,发现Apache FTP jar包没有提供对整个目录结构的上传和下载功能,只能非目录类型的文件进行上传和下载操作,后来我查阅很多网上的实现方法,再 ...

  5. 每天一个linux命令(目录文件操作):【转载】Linux 目录结构

    对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统至关重要,下面 ...

  6. Maven 目录结构[转载]

    转载至:http://www.cnblogs.com/haippy/archive/2012/07/05/2577233.html Maven 标准目录结构 好的目录结构可以使开发人员更容易理解项目, ...

  7. Linux目录结构及常用命令(转载)

    一.Linux目录结构 你想知道为什么某些程序位于/bin下,或者/sbin,或者/usr/bin,或/usr/sbin目录下吗?例如,less命令位于/usr/bin目录下.为什么没在/bin中,或 ...

  8. AndroidStudio2.2 Preview3中NDK开发之CMake和传统 JNI在目录结构和配置文件上的区别(转载)

    自从AndroidStudio更新到2.2,就有了CMake和传统JNI两种开发NDK的方法,主要就是在目录结构和build.gradle上的区别,下面我们将分别介绍目录区别和build.gradle ...

  9. Ionic 3 项目的工程目录结构(转载)

    工程目录结构说明如下图

随机推荐

  1. Caused by: java.sql.SQLSyntaxErrorException: ORA-00932: 数据类型不一致: 应为 NUMBER, 但却获得 BINARY

    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvo ...

  2. 去掉Word 标题编号变成黑框

    问题: 在使用Word编写文档时,提前拟好的标题编号会突然变成黑框(黑色的方框,黑色的矩形),如下图 解决方案: 1.将光标定位到标题中,紧邻黑框的右侧 2.按键盘左方向键使方框变成黑色 3.按键盘的 ...

  3. kubeadm 安装k8s

    环境要求: 机器名 ip地址 cpu和内存要求 kubernetes-master 10.0.0.11 2c2g(关闭swap) kubernetes-node1 10.0.0.12 2c2g(关闭s ...

  4. 常用sign算法

    所有参数包括appkey或者token拼接成&key=value格式 转小写 正序排序 MD5后得到sign

  5. arm-linux-ar 和 arm-linux-ranlib 的使用

    静态库是在编译时需要的库. 1. 建立一个静态库 [arm@localhost gcc]#arm­linux­ar ­r libhello.a h1.o h2.o 2. 为静态库建立索引 [arm@l ...

  6. VGDB提示

    由于之前地址的版本在未安装.Net 4.0的电脑上安装会出现插件使用装载失败的问题,已更新,新地址为:http://pan.baidu.com/s/1xdnuD,此版本需要.Net 2.0.

  7. 在Spring-boot中,为@Value注解添加从数据库读取properties支持

    一般我们会把常用的属性放在工程的classpath文件夹中,以property,yaml或json的格式进行文件存储,便于Spring-boot在初始化时获取. @Value则是Spring一个非常有 ...

  8. Spring知识点整理

    1.bean什么时候被实例化 第一:如果你使用BeanFactory作为Spring Bean的工厂类,则所有的bean都是在第一次使用该Bean的时候实例化第二:如果你使用ApplicationCo ...

  9. Mysql ---部署,创建用户

    版本:mysql-5.7.18-win32 步骤: 1 准备my.ini文件放在bin同级目录 My.ini文件可以设置bsedir/datadir/port等等 2 初始化数据库(5.7版本需要初始 ...

  10. yum -y install python-devel

    yum -y install python-devel的时候报错如图: Could not retrieve mirrorlist http://mirrorlist.centos.org/?rele ...