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 数据加密代码
Dec 24 Python
常见的在Python中实现单例模式的三种方法
Apr 08 Python
python通过加号运算符操作列表的方法
Jul 28 Python
python基于pyDes库实现des加密的方法
Apr 29 Python
Python中模块与包有相同名字的处理方法
May 05 Python
python3实现网络爬虫之BeautifulSoup使用详解
Dec 19 Python
python中hasattr()、getattr()、setattr()函数的使用
Aug 16 Python
python实现简易学生信息管理系统
Apr 05 Python
python将音频进行变速的操作方法
Apr 08 Python
python dict乱码如何解决
Jun 07 Python
python else语句在循环中的运用详解
Jul 06 Python
基于Python编写一个监控CPU的应用系统
Jun 25 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和.net的区别
2014/09/28 PHP
关于扩展 Laravel 默认 Session 中间件导致的 Session 写入失效问题分析
2016/01/08 PHP
Jquery+ajax请求data显示在GridView上(asp.net)
2010/08/27 Javascript
javascript自动改变文字大小和颜色的效果的小例子
2013/08/02 Javascript
JavaScript数值数组排序示例分享
2014/05/27 Javascript
jQuery+HTML5实现图片上传前预览效果
2015/08/20 Javascript
逐一介绍Jquery data()、Jquery stop()、jquery delay()函数(详)
2015/11/04 Javascript
jquery 实时监听输入框值变化的完美方法(必看)
2017/01/26 Javascript
有关JS中的0,null,undefined,[],{},'''''''',false之间的关系
2017/02/14 Javascript
canvas 实现中国象棋
2017/02/17 Javascript
利用JS对iframe父子(内外)页面进行操作的方法教程
2017/06/15 Javascript
浅谈从React渲染流程分析Diff算法
2018/09/08 Javascript
vue父组件给子组件的组件传值provide inject的方法
2019/10/23 Javascript
Element Popover 弹出框的使用示例
2020/07/26 Javascript
Python安装使用命令行交互模块pexpect的基础教程
2016/05/12 Python
python解决方案:WindowsError: [Error 2]
2016/08/28 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
2017/02/14 Python
50行Python代码实现人脸检测功能
2018/01/23 Python
Python使用爬虫抓取美女图片并保存到本地的方法【测试可用】
2018/08/30 Python
对python中的iter()函数与next()函数详解
2018/10/18 Python
Python中logging实例讲解
2019/01/17 Python
Gauss-Seidel迭代算法的Python实现详解
2019/06/29 Python
在keras 中获取张量 tensor 的维度大小实例
2020/06/10 Python
CSS3 Pie工具推荐--让IE6-8支持一些优秀的CSS3特性
2014/09/02 HTML / CSS
高级文秘工作总结的自我评价
2013/09/28 职场文书
自荐书模板
2013/12/15 职场文书
医学专业自荐信
2014/06/14 职场文书
餐厅周年庆活动方案
2014/08/25 职场文书
医生党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
感谢信格式范文
2015/01/22 职场文书
教师年度个人总结
2015/02/11 职场文书
团委副书记工作总结
2015/08/14 职场文书
领导莅临指导欢迎词
2015/09/30 职场文书
《失物招领》教学反思
2016/02/20 职场文书
python批量创建变量并赋值操作
2021/06/03 Python
Django+Celery实现定时任务的示例
2021/06/23 Python