客户端(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,支持多用户在线的更多相关文章

  1. python 开发一个支持多用户在线的FTP

    ### 作者介绍:* author:lzl### 博客地址:* http://www.cnblogs.com/lianzhilei/p/5813986.html### 功能实现 作业:开发一个支持多用 ...

  2. Python3学习之路~8.6 开发一个支持多用户在线的FTP程序-代码实现

    作业: 开发一个支持多用户在线的FTP程序 要求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp s ...

  3. (转)Python开发程序:支持多用户在线的FTP程序

    原文链接:http://www.itnose.net/detail/6642756.html 作业:开发一个支持多用户在线的FTP程序 要求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ...

  4. 老男孩python作业7-开发一个支持多用户在线的FTP程序

    作业6:开发一个支持多用户在线的FTP程序 要求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp s ...

  5. python之FTP程序(支持多用户在线)

    转发注明出处:http://www.cnblogs.com/0zcl/p/6259128.html 一.需求 1. 用户加密认证 (完成)2. 允许同时多用户登录 (完成)3. 每个用户有自己的家目录 ...

  6. 实现支持多用户在线的FTP程序(C/S)

    1. 需求 1. 用户加密认证 2. 允许多用户登录 3. 每个用户都有自己的家目录,且只能访问自己的家目录 4. 对用户进行磁盘分配,每一个用户的可用空间可以自己设置 5. 允许用户在ftp ser ...

  7. 开发一个支持多用户在线的FTP程序

    要求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp server上随意切换目录 允许用户查看当前目 ...

  8. CentOS随笔 - 2.CentOS7安装ftp支持(vsftpd)

    前言 转帖请注明出处: http://www.cnblogs.com/Troy-Lv5/ 在前一篇文章中介绍了在虚拟机中安装CentOS7, 接下来就要进行配置了, 第一个就是安装ftp支持. 要不然 ...

  9. 多用户在线FTP程序

    项目名:多用户在线FTP程序 一.需求 1.用户加密认证 2.允许同时多用户登录 3.每个用户有自己的家目录 ,且只能访问自己的家目录 4.对用户进行磁盘配额,每个用户的可用空间不同 5.允许用户在f ...

随机推荐

  1. Machine Learning in Action(2) 决策树算法

    决策树也是有监督机器学习方法. 电影<无耻混蛋>里有一幕游戏,在德军小酒馆里有几个人在玩20问题游戏,游戏规则是一个设迷者在纸牌中抽出一个目标(可以是人,也可以是物),而猜谜者可以提问题, ...

  2. CSS阶段总结

    CSS布局之左右布局与左中右布局 方法:为子元素设置浮动,然后在其父元素上使用clearfix类来清除浮动.代码示例: html部分: <div class="parent clear ...

  3. 坡道定点停车30cm

    坡道定点停车与起步是科目二五项必考之一,想要顺利通过该项考试,学员需要掌握两个要点,一个是车身距离右侧边线30cm以内的距离,一个是定点时机.本期,元贝小编先和大家分享半坡起步右边30公分怎么看.   ...

  4. zkui部署

    1.拉取代码 #git clone https://github.com/DeemOpen/zkui.git 2.构建并安装程序 #cd zkui/ #yum install -y maven #mv ...

  5. 使用libcurl进行HTTP GET操作

    Working example how to do a GET request with libcurl and save it to a string variable for future use ...

  6. cocoapod使用

    什么是cocoapod CocoaPods是用于方便使用第三方开源库的管理工具,减少我们对第三方库的各种配置. 安装教程参考: CocoaPods的介绍.安装.使用和原理 Cocoapod安装使用 第 ...

  7. DDD领域驱动之干货 (一)

    说道DDD不得不说传统的架构与DDD的架构区别. 传统的架构不外乎就是三层,而在这三层里面又不断的细分,始终没有达到想要的效果,那么为什么当时还是采用三层. 当然在DDD没有提出的时候三层是大多数人的 ...

  8. Java面向对象的三大特征详解

    一.封装(Encapsulation)       封装也称信息隐藏,是指利用抽象数据类型把数据和基于数据的操作封装起来,使其成为一个不可分割的整体,数据隐藏在抽象数据内部,尽可能的隐藏数据细节,只保 ...

  9. hdu-3018 Ant Trip(欧拉路径)

    题目链接: Ant Trip Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Others) ...

  10. 页面刷新 方法总结 JSP刷新[转]

    1) <meta http-equiv="refresh"content="10;url=跳转的页面"> 10表示间隔10秒刷新一次 2) < ...