socketserver+socket实现较为复杂的ftp,支持多用户在线
客户端(ftp_client.py)
import socketserver,json,hashlib,os
from pymongo import MongoClient '''
*****要点*****
1.面向对象编程
2.反射的利用
3.代码的高度解耦
4.md5加密传输认证
5.数据库查询验证
**************
'''
db = MongoClient('localhost', 27017)
curent_document = ''
#此类用于处理一系列客户端请求
class deal():
def __init__(self,name):
self.name = name #用户登录认证
def deal_login(self,data,client):
global logined_uname,db
BASE_DIR = ''#基目录
#选择数据库
d = db['DB_FOR_PYTHON']
#选择集合
users = d['FTP_USERS']
name = data['name']
pwd = data['pwd']
u = users.find_one({'name':name ,'pwd':pwd})
#用户不存在,返回0
if u == None or u == '':
#使用find()和find_one返回的结果分别是cursor和一条记录
u1 = users.find_one({'name':name})
if u1 == None or u1 == '':
#无此用户
client.send(b'')
return ''.encode()
else:
#密码有误
client.send(b'')
return ''.encode()
else:
#登录成功
client.send(b'')
logined_uname = name
return ''.encode() #上传处理
def deal_upload(self,data,request):
#查出用户的磁盘配额大小,并检查用户上传文件大小,和要上传的文件加以对比,看是否可以继续上传
user1 = db.DB_FOR_PYTHON.FTP_USERS.find_one({'name':logined_uname})
#用户的磁盘配额大小
space_limite = user1['space']
print('当前用户磁盘总空间:{}'.format(str(space_limite)))
name = data['name']
#上传文件大小
totalsize = data['size']*1024
m = hashlib.md5()
request.send('ok'.encode())
cur_size = 0
cur_content =b''
size = 0
global BASE_DIR
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
file_name = ''
#剩余磁盘大小
space = 0
u_dir = BASE_DIR+os.sep+'USERS_HOME'+os.sep+logined_uname.upper()+"_HOME"
if os.path.exists(u_dir):
# 用户总目录文件夹大小(bit计算)
real_space = (os.stat(u_dir).st_size)*1024
space = space_limite - real_space
file_name = u_dir+os.sep+name
else:
os.mkdir(u_dir)
space = space_limite
file_name = u_dir + os.sep + name
#如果上传资源的大小小于等于磁盘剩余空间,则继续
if space >= totalsize:
print('可以发送')
f = open(file_name,'wb')
while cur_size < totalsize:
if totalsize - cur_size >1024*1024:
size = 1024*1024
else:
size = totalsize - cur_size
print(size)
data = request.recv(size)
m.update(data)
cur_content += data
f.write(data)
cur_size += len(data)*1024
else:
print('haha')
f.close()
request.send(json.dumps({'state':'upload success!','md5':m.hexdigest()}).encode())
return json.dumps({'state':'upload success!','md5':m.hexdigest()}).encode()
else:
request.send(json.dumps({'state':'upload fail,your filesize exceeding the rest of your own space!','rest':space,'filesize':totalsize,'md5':None}).encode())
return json.dumps({'state':'upload fail,your filesize exceeding the rest of your own space!','rest':space,'filesize':totalsize,'md5':None}).encode()
#下载实现
def deal_download(self,data):
self.data = data['name']
return self.data
#用户切换目录
def deal_cd(self,data):
global BASE_DIR,curent_document
#当前用户基目录
ROOT_DOC = BASE_DIR+os.sep+'USERS_HOME'+os.sep+logined_uname.upper()+"_HOME"
current_document = ROOT_DOC
#用户输入的目录
manual_enter = data['cd_document']
current_document = os.chdir(manual_enter) if os.path.exists(manual_enter) else curent_document
print("用户要跳转的目录:",current_document)
pass
#查看文件
def deal_dir(self):
pass
#断点续传功能
def deal_cont(self):
pass
#面向对象的方式实现
class ftp_server(socketserver.BaseRequestHandler):
def handle(self):
logined_uname = ''
while True:
try:
#接收来自客户端的信息
data = self.request.recv(1024).decode()
data = json.loads(data)
print(data)
cmd = data['req']
#创建服务端对象
d = deal('ser')
if hasattr(d,cmd):
c = getattr(d,cmd)
res = c(data,self.request).decode()
print(res)
except ConnectionResetError as e:
print('error:',e)
break #主方法入口
if __name__ == '__main__':
HOST,PORT = 'localhost',9999
server = socketserver.ThreadingTCPServer((HOST,PORT),ftp_server)
server.serve_forever()
服务端(ftp_server.py)
# coding = utf-8 import socket,json,re,os,hashlib
login_uname = ''
class client_do(object):
def __init__(self,name):
self.name = name
#登录
def deal_login(self,data,client):
try:
global login_uname
global state
name = data.split()[1].split('\\')[0]
pwd = data.split()[1].split('\\')[1]
req = data.split()[0]
data = {
'req':req,
'name':name,
'pwd':pwd
}
client.send(json.dumps(data).encode())
response = client.recv(1024).decode()
if response == '':
login_uname = name
global lg_s
lg_s = '\033[32;1m $' + login_uname + '>>:\033[0m'
state = response
#返回结果可能为0(无此用户),1(验证成功),2(密码有误)
return response
except Exception as e:
print("登录出错:",e)
#上传
def deal_upload(self,mes,client):
try:
if state == '':
filename = mes.split()[1]
if os.path.isfile(filename):
f = open(filename, 'rb')
filesize = os.stat(filename).st_size
print('filesize:', filesize)
data = {
'req': mes.split()[0],
'name': filename,
'size': filesize,
'overwrite': True
}
client.send(json.dumps(data).encode())
# 接受服务器返回的信息,防止粘包,同时得到磁盘是否够传信息
res = client.recv(1024)
print('first response:', res.decode())
# 准备发送信息
m = hashlib.md5()
for line in f:
client.send(line)
m.update(line)
md5_client = m.hexdigest()
f.close()
# 接受服务器请求处理结果
response_info = client.recv(1024).decode()
response_info = json.loads(response_info)
md5_server = response_info['md5']
print('md5_client:{},\t md5_server:{}'.format(md5_client, md5_server))
print("状态:{}".format(response_info['state']))
#上传ok
return ''
else:
#上传出错
return ''
else:
print('请先完成登录')
except Exception as e:
print('上传出错:',e)
#用户切换目录
def deal_cd(self):
pass
#查看文件
def deal_dir(self):
pass
#断点续传功能
def deal_cont(self):
pass
client = socket.socket()
client.connect(('localhost',9999))
state = 0
lg_s =">>:"
while True:
mes = input(lg_s)
if mes == '' or mes ==None:continue
cl_req = mes.split()[0]
c = client_do('client')
if hasattr(c,cl_req):
s = getattr(c,cl_req)
res = s(mes,client)
else:
print('无效的命令')
说明:
代码实现的功能有用户登录认证,上传的前提是要登录,文件上传,用户磁盘配额,断点续传和目录跳转功能暂未实现。后续实现补上
运行截图:
1.数据库截图:

2.客户端截图:

3.服务端截图:

socketserver+socket实现较为复杂的ftp,支持多用户在线的更多相关文章
- python 开发一个支持多用户在线的FTP
### 作者介绍:* author:lzl### 博客地址:* http://www.cnblogs.com/lianzhilei/p/5813986.html### 功能实现 作业:开发一个支持多用 ...
- Python3学习之路~8.6 开发一个支持多用户在线的FTP程序-代码实现
作业: 开发一个支持多用户在线的FTP程序 要求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp s ...
- (转)Python开发程序:支持多用户在线的FTP程序
原文链接:http://www.itnose.net/detail/6642756.html 作业:开发一个支持多用户在线的FTP程序 要求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ...
- 老男孩python作业7-开发一个支持多用户在线的FTP程序
作业6:开发一个支持多用户在线的FTP程序 要求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp s ...
- python之FTP程序(支持多用户在线)
转发注明出处:http://www.cnblogs.com/0zcl/p/6259128.html 一.需求 1. 用户加密认证 (完成)2. 允许同时多用户登录 (完成)3. 每个用户有自己的家目录 ...
- 实现支持多用户在线的FTP程序(C/S)
1. 需求 1. 用户加密认证 2. 允许多用户登录 3. 每个用户都有自己的家目录,且只能访问自己的家目录 4. 对用户进行磁盘分配,每一个用户的可用空间可以自己设置 5. 允许用户在ftp ser ...
- 开发一个支持多用户在线的FTP程序
要求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp server上随意切换目录 允许用户查看当前目 ...
- CentOS随笔 - 2.CentOS7安装ftp支持(vsftpd)
前言 转帖请注明出处: http://www.cnblogs.com/Troy-Lv5/ 在前一篇文章中介绍了在虚拟机中安装CentOS7, 接下来就要进行配置了, 第一个就是安装ftp支持. 要不然 ...
- 多用户在线FTP程序
项目名:多用户在线FTP程序 一.需求 1.用户加密认证 2.允许同时多用户登录 3.每个用户有自己的家目录 ,且只能访问自己的家目录 4.对用户进行磁盘配额,每个用户的可用空间不同 5.允许用户在f ...
随机推荐
- Post Man 调用CRMAPI
官方文档 https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/webapi/setup-postman ...
- [数据挖掘课程笔记]SLIQ算法
1.数据结构 主要的数据结构有:1.Attribute List 2.Class List 对于数据集,每一个属性都有一个对应的Attribute List.如上图所示,每个Attribute Li ...
- appium():PageObject&PageFactory
Appium Java client has facilities which components to Page Object design pattern and Selenium PageFa ...
- 关于redis的思考
集群版本的redis主从复制 也可以实现集群 但是不是很好 集群版redis主从复制版本集群 Spring Boot整合Redi事务 Spring Boot+Redis+Ehcache实现二级缓存 S ...
- 什么是AWS Lambda?——事件驱动的函数执行环境
AWS CTO Werner Vogels在AWS re:Invent 2014大会的第二场主题演讲上公布了两个新服务和一系列新的实例,两个新服务都相当令人瞩目:第一个宣布的新服务是Amazon EC ...
- Canvas HTML5
不支持的时候记得: <canvas id="stockGraph" width="150" height="150"> curr ...
- Java(一)——认识Java语言
1.Java语言简介 Java是一种可以撰写跨平台应用程序的面向对象的程序设计语言,具有卓越的通用性.高效性.平台移植性和安全性.Sun 公司对 Java 编程语言的解释是:Java 编程语言是个简单 ...
- C语言文件读写总结
主要有四种: 1.文件的字符输入输出函数 fgetc fputc2.文件的字符串输入输出函数 fgets fputs3.文件的格式化输入输出函数 fscanf fprintf4.文件的数据块输入输出函 ...
- kali本機安裝openvas的血淚史復盤
安裝openvas的血淚史 因爲學習的需要,需要裝openvas,但是在虛擬機裏面,無論怎麼更新跟新源,總是會有問題,一氣之下,便不用虛擬機了,將自己的物理機刷成了kali機,從此便進了一個大坑. 安 ...
- Code:NFine目录
ylbtech-Code:NFine目录 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:http://ylb ...