首页 > 编程 > Python > 正文

Python实现基于多线程、多用户的FTP服务器与客户端功能完整实例

2020-02-16 02:06:21
字体:
来源:转载
供稿:网友

本文实例讲述了Python实现基于多线程、多用户的FTP服务器与客户端功能。分享给大家供大家参考,具体如下:

项目介绍:

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,pickleBASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))sys.path.append(BASEDIR)from conf import settingfrom core import file_handlerfrom core import db_handlerimport select,hashlibimport threadingdef 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()            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表