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 ...
随机推荐
- 【网络基础系列二】BOOTP、DHCP协议
BOOTP 含义:BOOT Protocol,引导协议 作用:引导无盘计算机或者第一次启动的计算机获取以下网络配置信息: 主机的IP地址.子网掩码 路由器(网关)的IP地址 DNS服务器IP地址 C/ ...
- Linux下MySQL、Apache、PHP源码安装全程实录(CentOS 6.4)
转自http://www.zjmainstay.cn/lamp-config 本文记录了我自己配置LAMP的全过程,借此记录一下,同时希望能够帮助一下需要帮助的LINUX新人,跟我一起学习,一起进步. ...
- FFMPEG more samples than frame size (avcodec_encode_audio2) 的解决方案
在实际的项目中,从音频设备采集到的音频的类型和编码器类型(aac ,amr)通常是不一致的. 那么我们首先需要做重采样的过程.利用swr_convert 重新采样. 这时候我们可能会遇到另外一个问题. ...
- hdu-5776 sum(同余)
题目链接: sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Pro ...
- 001-将Python源码转换为不需要环境的可执行文件
1 安装pyinstaller pip install pyinstaller #或者 pip3 install pyinstaller 2 生成打包文件 在命令行中输入 pyinstaller -F ...
- 一:MetaMq集群中单个节点的安装配置示意图
MetaMQ集群一个节点的安装和配置示意图[1]:下载metaMQ的安装包
- Python复习 基础知识
动态语言:变量类型不固定称之为动态语言 什么是动态语言呢? 可以简单的理解为直接被解释执行的语言称为动态语言. 而需要编译环境将程序转换为其它的编码再执行的语言称为静态语言. 当前静态语言有:jav ...
- 八、MyEclipse多次重装、删除注册表、重装系统激活都不成功,终极解决方法 - imsoft.cnblogs
MyEclipse(2010,2014)激活不成功的结论: [问题原因]激活不成功时,主要是激活的密钥文件.myeclipse.properties不在指定的位置.(一般都在D.E.F.G等盘符根目录 ...
- 3.清除dns缓存的意义及命令?
1.dos命令:ipconfig /flushdns 2.意义: 简单地说就是 www.baidu.com ,www.sina.com 这些就是DNS域名.但是计算机不能直接通过DNS域名访问服务器( ...
- python学习笔记——Thread常用方法
Thread对象中的一些方法: 以前说过多线程,用到threading模块中的Thread对象,其中的start和run方法比较熟悉了,start()是重载了Thread对象中的run方法,其实作用还 ...