开发简单的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. LeetCode 182. Duplicate Emails (查找重复的电子邮箱)

    题目标签: 题目给了我们一个 email 的table,让我们找到重复的 email. 可以建立 Person a, Person b, 找到两个表格中,emai 相等 但是 id 不同的 email ...

  2. 洛谷P3916 图的遍历

    题目链接:https://www.luogu.org/problemnew/show/P3916 题目大意 略. 分析 以终为始,逆向思维. 代码如下 #include <bits/stdc++ ...

  3. 内置Jetty配置JSP支持过程中的常见报错

    目录 1. 常见报错及解决 1.1 JSP support not configured 1.2 JSTL标签解析 1.3 JSP编译 1.4 JSP实现依赖 1.5 EL表达式支持 2. 小结 1. ...

  4. mycat-zookeepr--mycatweb

    ##############################mycat镜像############################## 5-1 创mycat镜像 wget http://dl.myca ...

  5. Codeforces 479【F】div3

    题目链接:http://codeforces.com/problemset/problem/977/F 题意:给你一串数字序列,让你求最长上升子序列,但是这个子序列呢,它的数字得逐渐连续挨着. 题解: ...

  6. 【Neo4j】踩坑大会-Neo4J用中文索引

    正在用的Neo4j是当前最新版:3.1.0,各种踩坑.说一下如何在Neo4j 3.1.0中使用中文索引.选用了IKAnalyzer做分词器. 1. 首先参考文章: https://segmentfau ...

  7. 可读性 vs 效率

    哪个重要. 应用层代码来说,实际上说任意一个重要都不为过, 但是到了内核里面之后,哪个重要. 肯定是效率阿,内核跑得慢,上面还有得玩么.

  8. Future Parttern 先给你这张提货单

    Future是未来,预期的意思,Thread-permessage模式是指将任务交给其他线程来做,但是如果想知道处理的结果,就要使用Future模式,它的典型应用时执行一个需要花一些时间的方法,会立即 ...

  9. 在 Mac 上使用 `sed` 命令的几个坑

    不可忽略的备份格式 sed -i 's/hello/world/g' hello.text 上面这行代码,可以在 linux 上运行,作用是将找到的 hello 替换为 world,并且直接保存修改到 ...

  10. 8_InlineHook

    1 shellcode低2Gb警告.应使用高2GB 稳定 : 在内核挂钩子: 由于每个进程的低2gb 的数据是不同的:所以 在内核挂钩子 因该把 代码 放在 高 2gb. 方法1(申请): 比如 使用 ...