项目介绍:

  1. 用户加密认证
  2. 允许同时多用户登录
  3. 每个用户有自己的家目录 ,且只能访问自己的家目录
  4. 对用户进行磁盘配额,每个用户的可用空间不同
  5. 允许用户在ftp server上随意切换目录
  6. 允许用户查看当前目录下文件
  7. 允许上传和下载文件,保证文件一致性
  8. 文件传输过程中显示进度条

实现的原理:

    服务器端启用端口监听,并对每一连接启用一个线程,对用户登陆密码采用SHA512进行加密并进行匹配,当用户登陆成功后,实例化FTPS,并引导客户端进入主命令模式,

  然后实现FTP的上传功能、下载功能、新建目录、删除文件或目录、切换目录等实例化操作,同时对相关上传下载进行进度条显示,服务器端显示下载或上传文件的大小等 

    客户端与服务器协商建立连接后,进行用户身份登陆,登陆成功接收服务器指令,转入命令输入窗口,同时对put 与 get命令进行判断,实现特定的上传与下载功能

核心代码实现如下:

  服务器端

  main.py

#!/usr/bin/env python3.5
# -*-coding:utf8-*-
import os,sys,socket,pickle
BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASEDIR)
from conf import setting
from core import file_handler
from core import db_handler
import select,hashlib
import threading
def login(username,password):
    """
    FTP登陆验证函数
    :param username:
    :param password:
    :return:

    # testDict ={"username":"jjb","password":"123456","file_dir":"E:\python","file_size":500}
    # file = 'jjb.pkl'
    # fp = open(file,'wb')
    # pickle.dump(testDict,fp)
    # fp.close()
    f = open("jjb.pkl","rb")
    data = pickle.loads(f.read())
    f.close()
    print(data)
    """
    #实例化加密函数
    hash = hashlib.sha512()
    db= db_handler.handler(setting.DATABASE,username)
    if os.path.isfile(db):
        f = open(db,"rb")
        data = pickle.loads(f.read())
        f.close()
        if username == data["name"]:
            hash.update(bytes(data["password"],"utf8"))
            hash_pwd = hash.hexdigest()
            if hash_pwd == password:
                filedir = data["file_dir"]
                filesize = data["file_size"]
                return "True|%s|%s"%(filedir,filesize)
            else:
                return "False||"
        else:
            return "False||"
    else:
        return "False||"
def process(conn,addr):
    flage = "False"
    # 接收客户端连接请求信息
    info = conn.recv(1000)
    if info.decode() == "connect":
        conn.send(bytes("login","utf8"))
    # 接收用户及密码信息
    while flage =="False":
        user_check =conn.recv(8000)
        # 分割用户名及密码
        username,password = str(user_check.decode()).split("|")
        # 调用登陆验证函数
        login_ack = login(username,password)
        flage,home,size = str(login_ack).split("|")
        # print(flage,home,size)
        # print("user_input:",username,"user_pass:",password)
        if flage =="True":
            # 登陆成功发送登陆确认信息给客户端
            conn.send(bytes("login_ack","utf8"))
            # 实例化FTPserver
            ftp = file_handler.FTPs(username,conn,home,size) # 登陆用户,数据连接,工作目录,磁盘配额
            ftp.run()
            break
        else:
            # 登陆失败,发送给客户端重新验证
            conn.send(bytes("登陆失败!","utf8"))


def ftp_server():
    '''
    启动FTP服务器端,开启线程监听
    :return:
    '''
    server = socket.socket()
    server.bind((setting.IP_PORT["host"],setting.IP_PORT["port"]))
    server.listen(10)
    while True:
        r,w,e = select.select([server,], [], [], 1)
        for i,server in enumerate(r):
            conn,addr = server.accept()
            # 创建线程
            t = threading.Thread(target=process, args=(conn, addr))
            # 启动线程
            t.start()
    server.close()
def run():
    ftp_server()

if __name__ =="__main__":
    run()
View Code

相关文章: