对MYFTP项目进行升级。扩展支持多用户并发访问与线程池。MYFTP项目请见python初学——网络编程之FTP服务器。
扩展需求
1.在之前开发的FTP基础上,开发支持多并发的功能
2.不能使用SocketServer模块,必须自己实现多线程
3.必须用到队列Queue模块,实现线程池
4.允许配置最大并发数,比如允许只有10个并发用户
需求模型
用例名
MYFTP
场景
- when:任意时间
- where:任何地点
- who:FTP用户
用例描述
- ftp使用用户名密码登录。密码需要加密认证、允许支持多用户登录。
- 每个用户有自己的家目录,所有的访问必须限制在用户的家目录。但在家目录中创建的目录可以进行目录切换。
- 用户的目录有磁盘配额。不允许超过磁盘配额。
- 用户可以查看当前目录下的文件列表。
- 用户可以上传和下载文件,并且保证文件的一致性。
- 文件的传输过程中显示精度条。
- 支持断点续传。
- 支持多用户并发访问
- 支持线程池
用户价值
实现一套自己的FTP服务端与客户端。
约束
线程池使用Queue模块实现
建模设计
UML图
顺序图
- 登录顺序图
程序讲解
程序主体
目录结构
在原来的lib目录中增加一个mythread.py的文件。该文件是一个使用Queue模块编写的线程池类。
+---bin # 执行程序目录
| create_user.py # 创建用户程序
| myftpc.py # ftp_server启动程序
| myftps.py # ftp_client启动程序
| __init__.py
|
+---conf
| | settings.py # 配置文件
| | __init__.py
| |
| \---__pycache__
|
+---core
| | logger.py # 日志生成文件
| | main.py # 主程序文件
| | __init__.py
| |
| \---__pycache__
|
+---db # 数据库目录
| \---accounts # 账号表目录
|---id_user_rs.json # 账号ID与用户名对应关系
+---file_upload # ftp文件服务器目录
+---lib # 类文件
| | account.py # 账号类
| | db.py # 数据库类
| | myftp_client.py # ftp客户端类
| | myftp_server.py # ftp服务端类
| | mythread.py # 线程池类(新增加内容)
| | process.py # 进度条展示类(暂时未使用)
| | __init__.py
| |
| \---__pycache__
\---log
__init__.py
mythread.py文件介绍
mythread使用队列简单实现了一个线程池的功能。
实现的方式比较简单,就是通过在队列中存放maxsize的线程对象。当客户端连接服务端后时从队列中拿取一个线程对象,创建自己的任务。执行完任务后再往队列中添加一个新的线程对象。
# -*-coding: utf-8 -*-
# Auther: Henry Yuan
import threading
import time
import queue
class MyThread():
"""
自定义的线程类,使用queue支持简单的线程池
"""
def __init__(self,maxsize):
"""
:param maxsize: 队列的数量
"""
self.maxsize=maxsize
self.q=queue.Queue(maxsize) # 初始化一个队列对象
# 在队列中先存放maxsize个队列对象。这一步就做到了线程池的作用。
for i in range(maxsize):
self.q.put(threading.Thread) # 在队列中先存放线程对象
def get_thread(self):
""" 从队列中拿取线程对象
:return:
"""
return self.q.get()
def put_thread(self):
""" 往队列中存放线程对象
:return:
"""
self.q.put(threading.Thread)
环境
本系统基于python 3.6版本开发。可运行在安装了python 3.6版本的linux或windows系统中。
用法
创建FTP用户
进入bin目录:
> cd bin
执行create_user.py:
> python ./create_user.py
Account:test2 # 用户名
Password:test2 # 密码
Home directory(test2): # 账号的根目录。默认为账号名称
Quota(bytes):10 # 账号的quota。默认为1G
===================ACCOUNT INFO===================
Account: test2
Home Dir: test2
Quota: 10
==================================================
启动ftp服务端
进入bin目录:
> cd bin
执行create_user.py:
> python ./myftps.py
启动ftp客户端
进入bin目录:
> cd bin
执行create_user.py:
> python ./myftpc.py
FTP用于登录:
Name:test2
Password:test2
Account [test2] login successful
ftp>:
客户端命令
-
ls: 查看用户当前目录的文件和目录列表
ftp>: ls 驱动器 D 中的卷是 新加卷 卷的序列号是 020D-6062 D:\deployment\MYFTP\file_upload\test2 的目录 2018/04/16 12:17 <DIR> . 2018/04/16 12:17 <DIR> .. 0 个文件 0 字节 2 个目录 45,605,543,936 可用字节 Directory [test2] list successful. ftp>:
-
pwd: 查看当前所在目录
ftp>: pwd Directory [\] show successful.
-
mdir: 创建目录
ftp>: mdir temp_dir Directory [temp_dir] create successful.
-
cd:切换目录
ftp>: cd temp_dir Directory [temp_dir] change successful.
-
put: 上传文件-支持断点续传
ftp>: get temp_file.md Start download -----> temp_file.md trandata: %s b'test123' [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]100% recvsize:7, filesize:7 File [temp_file.md] download successful.
-
get: 下载文件-支持断点续传
ftp>: put temp_file.md [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]100% File [temp_file.md] upload successful.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。