python实现ftp文件传输系统(案例分析)


Posted in Python onMarch 20, 2020

最近做了一个简单的文件传输系统,基于ftp协议,使用python语言开发,虽然python里面已经有ftplib模块,可以很容易的实现ftp服务器。这次我使用的是socket实现client与ftp server之间的通讯和文件传输,client另起一个flask服务器,用于用户在浏览器端的交互。系统实现的功能有:用户登录注册,用户查看ftp服务器端文件和下载上传删除操作,支持多进程、多用户。

一,登录注册

         该项目使用的是mongo数据库,其实用户登录注册功能很好实现,没有什么技术细节,这里就略过了。数据库管理代码如下:

import pymongo
from pymongo.collection import Collection
class DBManager(object):
 def __init__(self):
  client = pymongo.MongoClient("mongodb://localhost:27017/")
  self.db = client["FTPDB"]
  self.users = self.db['user']
 #保存用户登录信息
 def saveUserInfo(self,account,password):
  users = self.users.find()
  for item in users:
   accountDB = item['account']
   if accountDB == account:
    return "false"
  data = []
  userInfo = {}
  userInfo['account'] = account
  userInfo['password'] = password
  data.append(userInfo)
  collection = Collection(self.db,"user")
  collection.insert(data)
  return "true"
 def confirmUserLoginInfo(self,account,password):
  users = self.users.find()
  '''
   result状态: 1:表示初始状态,即不存在用户
      2:表示存在该用户、密码不正确
      3:验证成功
  '''
  result = 1
  for item in users:
   accountDB = item['account']
   passwordDB = item['password']
   if accountDB == account:
    if passwordDB == password:
     result = 3
    else:
     result = 2
  return result

前端注册js代码如下:

function register() {
 account = $("#account").val();
 password = $("#password").val();
 confirmPassword = $("#confirmPassword").val();
 if(account == null || password == null || confirmPassword == null){
  alert("请先输入必要信息")
  return;
 }
 if(password != confirmPassword){
  alert("密码不一致");
  return;
 }
 var request = {
  type:"register",
  account:account,
  password:password
 }
 sendData("http://localhost:8080/register",request)
}
//向服务器发送数据
function sendData(url,json) {
 $.ajax({
  url: url, //请求的url地址
  dataType: "json", //返回格式为json
  async: true, //请求是否异步,默认为异步,这也是ajax重要特性
  data: json, //参数值
  type: "post", //请求方式
  success:function(data){
   //alert(data)
   if(data.toString() == "false"){
    alert("用户名已存在");
   }else{
    window.location.href = "http://localhost:8080/index";
   }
  },
  error:function (error) {
   console.log(error);
  }
 });
}

二,文件管理(文件查看、删除、上传、下载)

客户端与服务器端约定命令格式,服务器通过解析客户端命令来执行操作。

server.py
from socket import *
import os,sys
import signal
import time
# 全局变量
HOST = '0.0.0.0'
PORT = 8686
ADDR = (HOST,PORT)
FILE_PATH = '../serverFiles/'
# 处理僵尸进程
signal.signal(signal.SIGCHLD,signal.SIG_IGN)
# 服务端功能类
class Server(object):
 def __init__(self):
  self.connfd = ""
 def do_list(self,account):
  # 获取文件列表
  file_list = os.listdir(FILE_PATH+account)
  if not file_list:
   self.connfd.send("服务器文件库为空".encode())
   return
  else:
   self.connfd.send(b"OK")
   time.sleep(0.1)
  files = ""
  for file in file_list:
   if file[0] != '.' and os.path.isfile(FILE_PATH + account +"/"+ file):
    files += file + '#'
  self.connfd.send(files.encode())
 def delete(self,accout,fileName):
  os.remove(FILE_PATH + accout + "/" + fileName)
  self.connfd.send(b"OK")
  time.sleep(0.1)
 def do_get(self,account,filename):
  try:
   fd = open(FILE_PATH + account +"/"+ filename,'rb')
  except IOError:
   self.connfd.send("文件不存在".encode())
   return
  else:
   #print("发送OK")
   self.connfd.send(b'OK')
   time.sleep(0.1)
  # 发送文件内容
  while True:
   data = fd.read(1024)
   if not data:
    time.sleep(0.1)
    self.connfd.send(b'##')
    break
   #print("正在发送数据")
   self.connfd.send(data)
  fd.close()
 def do_put(self,account,filename):
  if os.path.exists(FILE_PATH + account +"/"+ filename):
   self.connfd.send('该文件已存在'.encode())
   return
  fd = open(FILE_PATH + account +"/"+ filename,'wb')
  self.connfd.send(b'OK')
  # 接收文件内容
  while True:
   data = self.connfd.recv(1024)
   if data == b'**':
    break
   fd.write(data)
  fd.close()
 def socket_tcp(self):
  s = socket()
  s.setsockopt(SOL_SOCKET,SO_REUSEADDR,True)
  s.bind(ADDR)
  s.listen(5)
  print("Listen the port 8686...")
  return s
 def do_request(self,connfd):
  self.connfd = connfd
  while True:
   data = connfd.recv(1024).decode()
   datas = data.split(' ')
   if not data or datas[1] == 'QUIT@#':
    connfd.close()
    return
   elif datas[1] == "LIST@#":
    #print("list")
    self.do_list(datas[0])
   elif datas[1] == 'GET@#':
    filename = datas[-1]
    self.do_get(datas[0],filename)
   elif datas[1] == 'PUT@#':
    filename = datas[-1]
    self.do_put(datas[0],filename)
   elif datas[1] == 'delete@#':
    filename = datas[-1]
    self.delete(datas[0],filename)
 def run(self):
  # 创建套接字
  s = self.socket_tcp()
  while True:
   try:
    connfd,addr = s.accept()
   except KeyboardInterrupt:
    sys.exit("服务器退出")
   except Exception as e:
    print(e)
    continue
   print("Connect from",addr)
   # 创建子进程
   pid = os.fork()
   if pid == 0:
    s.close()
    self.do_request(connfd) #处理客户端具体请求
    os._exit(0)
   else:
    connfd.close()
if __name__ == "__main__":
 server = Server()
 server.run()
client.py
"""
 client.py
"""
import socket
import os,sys
import time
# 服务器地址
ADDR = ("127.0.0.1",8686)
FILE_PATH = "./clientFiles/"
# 客户端功能类
class Client(object):
 def __init__(self,account):
  self.sockfd = ""
  self.account = account
 #获得服务器文件列表
 def server_list(self):
  ftpServerFiles = []
  self.sockfd.send((self.account+' LIST@# ').encode())
  # 等待回复
  data = self.sockfd.recv(128).decode()
  if data == "OK":
   files = self.sockfd.recv(4096).decode()
   for file in files.split('#'):
    #print(file)
    ftpServerFiles.append(file)
  else:
   # 无法完成操作
   print(data)
  ftpServerFiles = ftpServerFiles[:-1]
  return ftpServerFiles
 #获得用户文件夹列表
 def client_list(self):
  # 获取文件列表
  userFiles = []
  file_list = os.listdir(FILE_PATH+self.account+"/")
  if not file_list:
   return
  else:
   time.sleep(0.1)
  files = ""
  for file in file_list:
   if file[0] != '.' and os.path.isfile(FILE_PATH + self.account + "/" + file):
    userFiles.append(file)
  return userFiles
 #退出
 def do_quit(self):
  self.sockfd.send((self.account+' QUIT@# ').encode())
  self.sockfd.close()
  sys.exit('谢谢使用')
 #用户下载服务器文件
 def do_get(self,filename):
  self.sockfd.send((self.account+' GET@# '+filename).encode())
  data = self.sockfd.recv(128).decode()
  if data == 'OK':
   fd = open(FILE_PATH + self.account + "/" + filename,'wb')
   #复写
   while True:
    data = self.sockfd.recv(1024)
    if data == b'##':
     #print("##")
     break
    #print("正在写入数据")
    fd.write(data)
   fd.close()
  else:
   print(data)
 #用户将文件上传到服务器文件夹
 def do_put(self,filename):
  try:
   fd = open(FILE_PATH + self.account + "/" + filename,'rb')
  except IOError:
   print("文件不存在")
   return
  # 获取文件名
  filename = filename.split('/')[-1]
  # else:
  self.sockfd.send((self.account+' PUT@# '+filename).encode())
  data = self.sockfd.recv(128).decode()
  # 发送文件
  if data == 'OK':
   while True:
    data = fd.read(1024)
    if not data:
     time.sleep(0.1)
     self.sockfd.send(b'**')
     break
    self.sockfd.send(data)
   fd.close()
   return "true"
  else:
   print(data)
   return "false"
 #删除用户文件
 def removeU(self,fileName):
  os.remove(FILE_PATH + self.account + "/" + fileName)
  return "true"
 #删除用户文件
 def removeF(self,fileName):
  self.sockfd.send((self.account+' delete@# '+fileName).encode())
  # 等待回复
  data = self.sockfd.recv(128).decode()
  if data == "OK":
   return "true"
 def menu_display(self):
  print("\n------命令选择-------")
  print("*** clist  ***")
  print("*** slist  ***")
  print("*** get list  ***")
  print("*** put list  ***")
  print("*** quit  ***")
  print("----------------------")
 def run(self,cmd):
  # 创建套接字
  sockfd = socket.socket()
  try:
   sockfd.connect(ADDR)
  except Exception as e:
   print(e)
   return
  result = ""
  self.sockfd = sockfd
  # choice(cmd,ftp)
  if cmd == "slist":
   result = self.server_list()
   return result
  elif cmd == "clist":
   result = self.client_list()
   return result
  elif cmd =='quit':
   self.do_quit()
  elif cmd[:3] == 'get':
   filename = cmd.strip().split(' ')[-1]
   self.do_get(filename)
  elif cmd[:3] == 'put':
   filename = cmd.strip().split(' ')[-1]
   result = self.do_put(filename)
   return result
  elif cmd[:7] == 'removeU':
   filename = cmd.strip().split(' ')[-1]
   self.removeU(filename)
  elif cmd[:7] == 'removeF':
   filename = cmd.strip().split(' ')[-1]
   self.removeF(filename)
  else:
   print("请输入正确命令!")
if __name__ == "__main__":
 client = Client("ffy")
 client.run()

运行界面:

python实现ftp文件传输系统(案例分析)

python实现ftp文件传输系统(案例分析) 

总结 

到此这篇关于python实现ftp文件传输系统的文章就介绍到这了,更多相关python ftp文件传输内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python中执行shell命令的几个方法小结
Sep 18 Python
python实现根据窗口标题调用窗口的方法
Mar 13 Python
在Python中使用cookielib和urllib2配合PyQuery抓取网页信息
Apr 25 Python
利用Python操作消息队列RabbitMQ的方法教程
Jul 19 Python
快速了解python leveldb
Jan 18 Python
Python 函数基础知识汇总
Mar 09 Python
python实现俄罗斯方块
Jun 26 Python
DataFrame.to_excel多次写入不同Sheet的实例
Dec 02 Python
在Django中自定义filter并在template中的使用详解
May 19 Python
Windows下pycharm安装第三方库失败(通用解决方案)
Sep 17 Python
python归并排序算法过程实例讲解
Nov 04 Python
jupyter notebook快速入门及使用详解
Nov 13 Python
关于Python 中的时间处理包datetime和arrow的方法详解
Mar 19 #Python
JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解
Mar 19 #Python
Python文件操作基础流程解析
Mar 19 #Python
Python函数基本使用原理详解
Mar 19 #Python
Python ATM功能实现代码实例
Mar 19 #Python
详解django使用include无法跳转的解决方法
Mar 19 #Python
Django模板标签中url使用详解(url跳转到指定页面)
Mar 19 #Python
You might like
PHP原理之异常机制深入分析
2010/08/08 PHP
ThinkPHP模板替换与系统常量及应用实例教程
2014/08/22 PHP
Laravel 4.2 中队列服务(queue)使用感受
2014/10/30 PHP
Nigma vs Alliance BO5 第二场2.14
2021/03/10 DOTA
一个js实现的所谓的滑动门
2007/05/23 Javascript
Javascript图像处理—为矩阵添加常用方法
2012/12/27 Javascript
js模拟点击以提交表单为例兼容主流浏览器
2013/11/29 Javascript
JS获取几种URL地址的方法小结
2014/02/26 Javascript
Javascript实现单张图片浏览
2014/12/18 Javascript
分享一则javascript 调试技巧
2015/01/02 Javascript
谷歌showModalDialog()方法不兼容出现对话窗口的解决办法
2016/02/15 Javascript
关于微信jssdk实现多图片上传的一点心得分享
2016/12/13 Javascript
JS作用域深度解析
2016/12/29 Javascript
jQuery Plupload上传插件的使用
2017/04/19 jQuery
Vue2.0利用vue-resource上传文件到七牛的实例代码
2017/07/28 Javascript
input输入框内容实时监测(附代码)
2017/08/15 Javascript
angular4 如何在全局设置路由跳转动画的方法
2017/08/30 Javascript
mac中利用NVM管理不同node版本的方法详解
2017/11/08 Javascript
基于iview的router常用控制方式
2019/05/30 Javascript
详解vue微信网页授权最终解决方案
2019/06/16 Javascript
JS定时器如何实现提交成功提示功能
2020/06/12 Javascript
Python基于pillow判断图片完整性的方法
2016/09/18 Python
python开发利器之ulipad的使用实践
2017/03/16 Python
Pandas库之DataFrame使用的学习笔记
2019/06/21 Python
Django ORM 常用字段与不常用字段汇总
2019/08/09 Python
Django+python服务器部署与环境部署教程详解
2020/03/30 Python
Python实现常见的几种加密算法(MD5,SHA-1,HMAC,DES/AES,RSA和ECC)
2020/05/09 Python
Sam’s Club山姆会员商店:沃尔玛旗下高端会员制商店
2017/01/16 全球购物
酒吧总经理岗位职责
2013/12/10 职场文书
户籍证明的格式
2014/01/13 职场文书
十岁生日家长答谢词
2014/01/17 职场文书
党课培训主持词
2014/04/01 职场文书
《假如》教学反思
2014/04/17 职场文书
小学兴趣小组活动总结
2014/07/07 职场文书
2014年大学生村官工作总结
2014/11/19 职场文书
CSS作用域(样式分割)的使用汇总
2021/11/07 HTML / CSS