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 文件重命名工具代码
Jul 26 Python
用实例说明python的*args和**kwargs用法
Nov 01 Python
Python实现合并字典的方法
Jul 07 Python
在python3.5中使用OpenCV的实例讲解
Apr 02 Python
python3实现逐字输出的方法
Jan 23 Python
对python中的try、except、finally 执行顺序详解
Feb 18 Python
Django集成CAS单点登录的方法示例
Jun 10 Python
Python面向对象之Web静态服务器
Sep 03 Python
树莓派安装OpenCV3完整过程的实现
Oct 10 Python
python批量生成条形码的示例
Oct 10 Python
Django使用django-simple-captcha做验证码的实现示例
Jan 07 Python
用python修改excel表某一列内容的操作方法
Jun 11 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
WHOIS类的修改版
2006/10/09 PHP
php 用sock技术发送邮件的函数
2007/07/21 PHP
php魔术函数__call()用法实例分析
2015/02/13 PHP
thinkphp3.2点击刷新生成验证码
2016/02/16 PHP
简单的自定义php模板引擎
2016/08/26 PHP
php使用SAE原生Mail类实现各种类型邮件发送的方法
2016/10/10 PHP
phpstorm最新激活码分享亲测phpstorm2020.2.3版可用
2020/11/22 PHP
菜鸟学习JavaScript小实验之函数引用
2010/11/17 Javascript
用JavaScript仿PS里的羽化效果代码
2011/12/20 Javascript
javascript面向对象程序设计(一)
2015/01/29 Javascript
详解JavaScript数组的操作大全
2015/10/19 Javascript
JS判断是否长按某一键的方法
2016/03/02 Javascript
js获取时间函数及扩展函数的方法
2016/10/30 Javascript
JS正则子匹配实例分析
2016/12/22 Javascript
Angular.js中ng-if、ng-show和ng-hide的区别介绍
2017/01/20 Javascript
Javascript中数组去重与拍平的方法示例
2017/02/03 Javascript
Vue组件开发初探
2017/02/14 Javascript
select自定义小三角样式代码(实用总结)
2017/08/18 Javascript
基于JSON数据格式详解
2017/08/31 Javascript
Vue导出json数据到Excel电子表格的示例
2017/12/04 Javascript
vue+高德地图写地图选址组件的方法
2019/05/18 Javascript
vue实现固定位置显示功能
2019/05/30 Javascript
使用vuex较为优雅的实现一个购物车功能的示例代码
2019/12/09 Javascript
实例讲解React 组件生命周期
2020/07/08 Javascript
Python使用sorted排序的方法小结
2017/07/28 Python
python 删除大文件中的某一行(最有效率的方法)
2017/08/19 Python
python sys,os,time模块的使用(包括时间格式的各种转换)
2018/04/27 Python
python traceback捕获并打印异常的方法
2018/08/31 Python
Python多线程应用于自动化测试操作示例
2018/12/06 Python
Python程序慢的重要原因
2020/09/04 Python
Python 实现键盘鼠标按键模拟
2020/11/18 Python
销售团队口号大全
2014/06/06 职场文书
卖房协议书样本
2014/10/30 职场文书
2016年社区服务活动总结
2016/04/06 职场文书
历史名人教你十五个读书方法,赶快Get起来!
2019/07/18 职场文书
《吸血鬼幸存者》新内容发布 追加多个全新模式
2022/04/07 其他游戏