• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

python,Pyqt5 实现FTP服务器和客户端文件上传,下载

武飞扬头像
雁过留声--
帮助1

前言

ftp协议即文件传输协议,人生苦短,我用python,对于编程新手写个ftp服务器及客户端,python绝对是很好的选择,本人用python pyftpdlib模块编写了ftp服务器,也使用pyqt5编写了简单的FTP客户端实现ftp服务器链接文件上传,下载等功能。

一.FTP链接服务端,文件读取上传,下载功能展示

1.链接FTP服务器

填写ftp服务器链接主机ip地址,用户名,密码,端口号,点击链接按钮,看到打印链接成功信息及成功链接上ftp服务器,可在下方查看ftp服务器文件。

学新通

2.上传文件到FTP服务器

右击链接FTP服务器的文件点击上传按钮,可选择要上传的文件

学新通

选择要上传的文件:

学新通

 看到如下图打印上传文件成功信息,即文件成功上传到Ftp服务器,上传成功后可以在下方Ftp服务器的文件夹中看到上传的文件。

学新通

3.下载文件到本地

右击链接FTP服务器的文件点击下载按钮:

学新通

看到如下图打印下载文件成功信息,即文件成功从Ftp服务器下载到本地,可以在本地打开下载的文件: 

学新通

二.ftp服务端主要代码

  1.  
    from pyftpdlib.authorizers import DummyAuthorizer
  2.  
    from pyftpdlib.handlers import FTPHandler
  3.  
    from pyftpdlib.servers import FTPServer
  4.  
     
  5.  
    class FtpServer:
  6.  
     
  7.  
    def ftpStart(self):
  8.  
    # 实例化虚拟用户,这是FTP验证首要条件
  9.  
    authorizer = DummyAuthorizer()
  10.  
     
  11.  
    authorizer.add_user('user', '12345', 'D:/ftpFile', perm='elradfmw')
  12.  
    # 添加匿名用户 只需要路径
  13.  
    authorizer.add_anonymous('D:/ftpFile/test')
  14.  
     
  15.  
    handler = FTPHandler
  16.  
    handler.authorizer = authorizer
  17.  
    # 添加被动端口范围
  18.  
    handler.passive_ports = range(2000, 8333)
  19.  
    # 监听ip 和 端口,使用21端口
  20.  
    server = FTPServer(('127.0.0.1', 21), handler)
  21.  
    # server.set_pasv(False)
  22.  
    # 开始服务
  23.  
    server.serve_forever()
学新通

 三.客户端主要代码

  1.  
    # -*- coding: utf-8 -*-
  2.  
     
  3.  
    # Form implementation generated from reading ui file 'FtpGui.ui'
  4.  
    #
  5.  
    # Created by: PyQt5 UI code generator 5.15.4
  6.  
    #
  7.  
    # WARNING: Any manual changes made to this file will be lost when pyuic5 is
  8.  
    # run again. Do not edit this file unless you know what you are doing.
  9.  
    from tqdm import tqdm
  10.  
    import os
  11.  
    import sys
  12.  
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  13.  
    sys.path.insert(0, BASE_DIR)
  14.  
    from FtpClientOperation import FtpClient
  15.  
    from PyQt5.QtGui import QIcon,QCursor
  16.  
    from PyQt5.QtCore import Qt, QUrl, QCoreApplication
  17.  
    from PyQt5 import QtCore, QtGui, QtWidgets
  18.  
    from PyQt5.QtWidgets import QMessageBox, QMenu, QAction, QFileDialog, QProgressBar, QProgressDialog
  19.  
     
  20.  
    from utils.StringUtils import isNull,isNotNull
  21.  
     
  22.  
    class Ui_MainWindow(object):
  23.  
    def setupUi(self, MainWindow):
  24.  
    self.MainWindow = MainWindow
  25.  
    MainWindow.setObjectName("MainWindow")
  26.  
    MainWindow.resize(384, 489)
  27.  
    icon = QtGui.QIcon()
  28.  
    icon.addPixmap(QtGui.QPixmap("../image/icon/FTP.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
  29.  
    MainWindow.setWindowIcon(icon)
  30.  
    self.centralwidget = QtWidgets.QWidget(MainWindow)
  31.  
    self.centralwidget.setObjectName("centralwidget")
  32.  
    self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
  33.  
    self.verticalLayout.setObjectName("verticalLayout")
  34.  
    self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
  35.  
    self.horizontalLayout_3.setObjectName("horizontalLayout_3")
  36.  
    self.toolButton = QtWidgets.QToolButton(self.centralwidget)
  37.  
    icon1 = QtGui.QIcon()
  38.  
    icon1.addPixmap(QtGui.QPixmap("../image/icon/FTP.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
  39.  
    self.toolButton.setIcon(icon1)
  40.  
    self.toolButton.setObjectName("toolButton")
  41.  
    self.horizontalLayout_3.addWidget(self.toolButton)
  42.  
    self.verticalLayout.addLayout(self.horizontalLayout_3)
  43.  
    self.horizontalLayout = QtWidgets.QHBoxLayout()
  44.  
    self.horizontalLayout.setObjectName("horizontalLayout")
  45.  
    self.label = QtWidgets.QLabel(self.centralwidget)
  46.  
    self.label.setObjectName("label")
  47.  
    self.horizontalLayout.addWidget(self.label)
  48.  
    self.lineEdit_3 = QtWidgets.QLineEdit(self.centralwidget)
  49.  
    self.lineEdit_3.setObjectName("lineEdit_3")
  50.  
    self.horizontalLayout.addWidget(self.lineEdit_3)
  51.  
    self.label_2 = QtWidgets.QLabel(self.centralwidget)
  52.  
    self.label_2.setObjectName("label_2")
  53.  
    self.horizontalLayout.addWidget(self.label_2)
  54.  
    self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
  55.  
    self.lineEdit_2.setObjectName("lineEdit_2")
  56.  
    self.horizontalLayout.addWidget(self.lineEdit_2)
  57.  
    self.label_3 = QtWidgets.QLabel(self.centralwidget)
  58.  
    self.label_3.setObjectName("label_3")
  59.  
    self.horizontalLayout.addWidget(self.label_3)
  60.  
    self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
  61.  
    self.lineEdit.setObjectName("lineEdit")
  62.  
    self.horizontalLayout.addWidget(self.lineEdit)
  63.  
    self.label_4 = QtWidgets.QLabel(self.centralwidget)
  64.  
    self.label_4.setObjectName("label_4")
  65.  
    self.horizontalLayout.addWidget(self.label_4)
  66.  
    self.lineEdit_4 = QtWidgets.QLineEdit(self.centralwidget)
  67.  
    self.lineEdit_4.setObjectName("lineEdit_4")
  68.  
    self.horizontalLayout.addWidget(self.lineEdit_4)
  69.  
    self.pushButton = QtWidgets.QPushButton(self.centralwidget)
  70.  
    self.pushButton.setObjectName("pushButton")
  71.  
    self.horizontalLayout.addWidget(self.pushButton)
  72.  
    self.verticalLayout.addLayout(self.horizontalLayout)
  73.  
    self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
  74.  
    self.textBrowser.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
  75.  
    self.textBrowser.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
  76.  
    self.textBrowser.setLineWrapMode(0)
  77.  
    self.textBrowser.setObjectName("textBrowser")
  78.  
    self.verticalLayout.addWidget(self.textBrowser)
  79.  
    self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
  80.  
    self.horizontalLayout_2.setObjectName("horizontalLayout_2")
  81.  
    self.label_5 = QtWidgets.QLabel(self.centralwidget)
  82.  
    self.label_5.setObjectName("label_5")
  83.  
    self.horizontalLayout_2.addWidget(self.label_5)
  84.  
    self.lineEdit_5 = QtWidgets.QLineEdit(self.centralwidget)
  85.  
    self.lineEdit_5.setObjectName("lineEdit_5")
  86.  
    self.horizontalLayout_2.addWidget(self.lineEdit_5)
  87.  
    self.verticalLayout.addLayout(self.horizontalLayout_2)
  88.  
    self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
  89.  
    self.horizontalLayout_4.setObjectName("horizontalLayout_4")
  90.  
    self.treeWidget = QtWidgets.QTreeWidget(self.centralwidget)
  91.  
    self.treeWidget.setColumnCount(4)
  92.  
    self.treeWidget.setObjectName("treeWidget")
  93.  
    item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
  94.  
    self.horizontalLayout_4.addWidget(self.treeWidget)
  95.  
    self.verticalLayout.addLayout(self.horizontalLayout_4)
  96.  
    MainWindow.setCentralWidget(self.centralwidget)
  97.  
    self.statusbar = QtWidgets.QStatusBar(MainWindow)
  98.  
    self.statusbar.setObjectName("statusbar")
  99.  
    MainWindow.setStatusBar(self.statusbar)
  100.  
     
  101.  
    self.retranslateUi(MainWindow)
  102.  
    self.pushButton.clicked.connect(self.connectFtp)
  103.  
    self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu) # 打开右键菜单的策略
  104.  
    self.treeWidget.customContextMenuRequested.connect(self.treeWidgetItem_fun) # 绑定事件
  105.  
    QtCore.QMetaObject.connectSlotsByName(MainWindow)
  106.  
     
  107.  
    def retranslateUi(self, MainWindow):
  108.  
    _translate = QtCore.QCoreApplication.translate
  109.  
    MainWindow.setWindowTitle(_translate("MainWindow", "FTP Client"))
  110.  
    self.toolButton.setText(_translate("MainWindow", "file"))
  111.  
    self.label.setText(_translate("MainWindow", "主机:"))
  112.  
    self.label_2.setText(_translate("MainWindow", "用户名:"))
  113.  
    self.label_3.setText(_translate("MainWindow", "密码:"))
  114.  
    self.label_4.setText(_translate("MainWindow", "端口号:"))
  115.  
    self.lineEdit_3.setText(_translate("MainWindow", "127.0.0.1"))
  116.  
    self.lineEdit_2.setText(_translate("MainWindow", "user"))
  117.  
    self.lineEdit.setText(_translate("MainWindow", "12345"))
  118.  
    self.lineEdit.setEchoMode(QtWidgets.QLineEdit.Password)
  119.  
    self.lineEdit_4.setText(_translate("MainWindow", "21"))
  120.  
    self.pushButton.setText(_translate("MainWindow", "链接"))
  121.  
    self.label_5.setText(_translate("MainWindow", "链接远程站点:"))
  122.  
    self.treeWidget.headerItem().setText(0, _translate("MainWindow", "文件名"))
  123.  
    self.treeWidget.headerItem().setText(1, _translate("MainWindow", "文件大小"))
  124.  
    self.treeWidget.headerItem().setText(2, _translate("MainWindow", "文件类型"))
  125.  
    self.treeWidget.headerItem().setText(3, _translate("MainWindow", "最新修改时间"))
  126.  
    __sortingEnabled = self.treeWidget.isSortingEnabled()
  127.  
    self.treeWidget.setSortingEnabled(False)
  128.  
    self.treeWidget.topLevelItem(0).setText(0, _translate("MainWindow", "/"))
  129.  
    self.treeWidget.topLevelItem(0).setText(2, _translate("MainWindow", "directory"))
  130.  
    self.treeWidget.topLevelItem(0).setIcon(0, QIcon('../image/icon/folder.png'))
  131.  
    self.treeWidget.setSortingEnabled(__sortingEnabled)
  132.  
    def connectFtp(self):
  133.  
    addr=self.lineEdit_3.text();
  134.  
    userName=self.lineEdit_2.text();
  135.  
    password=self.lineEdit.text();
  136.  
    port=self.lineEdit.text()
  137.  
    print("哈哈" addr "," userName "," password)
  138.  
    if isNull(addr)==True or isNull(userName)==True or isNull(password)==True:
  139.  
    QMessageBox.information(self.MainWindow, '警告', 'ftp ip地址或用户名或密码不能为空,请检查!', QMessageBox.Ok | QMessageBox.Close,
  140.  
    QMessageBox.Close)
  141.  
    else:
  142.  
    self.ftpOperation=FtpClient(addr,int(port))
  143.  
    ftpclient=self.ftpOperation.ftp_connect(userName,password)
  144.  
    print("ftp:" ftpclient.getwelcome())
  145.  
    self.textBrowser.append(ftpclient.getwelcome())
  146.  
    self.textBrowser.append("ftp:" addr " 链接成功!")
  147.  
    ftpPath=ftpclient.pwd()
  148.  
    self.lineEdit_5.setText(ftpPath)
  149.  
    _translate = QtCore.QCoreApplication.translate
  150.  
    print(ftpPath)
  151.  
    self.treeWidget.topLevelItem(0).setText(0, _translate("MainWindow", ftpPath))
  152.  
     
  153.  
    top_file_list=ftpclient.getdirs(ftpPath)
  154.  
    for i in range(len(top_file_list)):
  155.  
    self.treeWidget.topLevelItem(0).addChild(QtWidgets.QTreeWidgetItem())
  156.  
    #['20221104135530', 'perm=radfw', 'size=53990', 'type=file']
  157.  
    self.treeWidget.topLevelItem(0).child(i).setText(0, _translate("MainWindow", top_file_list[i]))
  158.  
    modify_time = ftpclient.get_modify_time(ftpPath top_file_list[i]).split(";")
  159.  
    self.treeWidget.topLevelItem(0).child(i).setText(1, _translate("MainWindow", modify_time[2][5:-1]))
  160.  
    self.treeWidget.topLevelItem(0).child(i).setText(3, _translate("MainWindow", modify_time[0]))
  161.  
    if ftpclient.checkFileDir(ftpPath top_file_list[i]) == "Dir":
  162.  
    self.treeWidget.topLevelItem(0).child(i).setText(2, _translate("MainWindow", "directory"))
  163.  
    self.treeWidget.topLevelItem(0).child(i).setIcon(0, QIcon('../image/icon/folder.png'))
  164.  
    self.addTreeItem(ftpclient, ftpPath top_file_list[i], self.treeWidget.topLevelItem(0).child(i),
  165.  
    _translate)
  166.  
    else:
  167.  
    self.treeWidget.topLevelItem(0).child(i).setIcon(0,QIcon('../image/icon/file.png'))
  168.  
    self.treeWidget.topLevelItem(0).child(i).setText(2, _translate("MainWindow", "file"))
  169.  
     
  170.  
    print(top_file_list)
  171.  
    def addTreeItem(self,ftpclient,filePath,parentItem,_translate):
  172.  
    file_list = ftpclient.getdirs(filePath)
  173.  
    for i in range(len(file_list)):
  174.  
    parentItem.addChild(QtWidgets.QTreeWidgetItem())
  175.  
    parentItem.child(i).setText(0, _translate("MainWindow", file_list[i]))
  176.  
    modify_time = ftpclient.get_modify_time(filePath "/" file_list[i]).split(";")
  177.  
    parentItem.child(i).setText(1, _translate("MainWindow", modify_time[2][5:-1]))
  178.  
    parentItem.child(i).setText(3, _translate("MainWindow", modify_time[0]))
  179.  
    if ftpclient.checkFileDir(filePath "/" file_list[i]) == "Dir":
  180.  
    parentItem.child(i).setIcon(0, QIcon('../image/icon/folder.png'))
  181.  
    parentItem.child(i).setText(2,_translate("MainWindow", "directory" ))
  182.  
    self.addTreeItem(ftpclient, filePath "/" file_list[i], parentItem.child(i),
  183.  
    _translate)
  184.  
    else:
  185.  
    parentItem.child(i).setIcon(0, QIcon('../image/icon/file.png'))
  186.  
    parentItem.child(i).setText(2, _translate("MainWindow", "file"))
  187.  
     
  188.  
    # 定义treewidget中item右键界面
  189.  
    def treeWidgetItem_fun(self, pos):
  190.  
    item = self.treeWidget.currentItem()
  191.  
    item1 = self.treeWidget.itemAt(pos)
  192.  
     
  193.  
    if item != None and item1 != None: # 判断菜单是否为空
  194.  
    popMenu = QMenu()
  195.  
    if item.text(2)=="directory":
  196.  
    self.upload=popMenu.addAction(QAction(u'上传', self.treeWidget))
  197.  
    else:
  198.  
    self.download=popMenu.addAction(QAction(u'下载', self.treeWidget))
  199.  
    popMenu.triggered[QAction].connect(self.processtrigger) # 右键点击清空之后执行的操作
  200.  
    popMenu.exec_(QCursor.pos()) # 执行之后菜单可以显示
  201.  
     
  202.  
    # 右键点击清空之后执行的操作
  203.  
    def processtrigger(self, q):
  204.  
    # 相应的处理
  205.  
    command = q.text()
  206.  
    item = self.treeWidget.currentItem()
  207.  
    filePath=self.getLocation(item)
  208.  
    print(filePath)
  209.  
    if command == "上传":
  210.  
    self.ftpOperation.ftpClient.cwd(filePath)
  211.  
    fileUrl = QFileDialog.getOpenFileUrl(None, '打开文件', QUrl('.'),'所有文件(*.*);;Python文件(*.py);;图片(*.png *.jpg)')
  212.  
    if fileUrl[0]!=None and isNotNull(fileUrl[0].path()):
  213.  
    pathFile=fileUrl[0].path().strip("/")
  214.  
    self.textBrowser.append("上传文件:" pathFile)
  215.  
    self.textBrowser.append("正在上传文件:" pathFile " 到" filePath)
  216.  
    res=self.ftpOperation.upload(pathFile)
  217.  
    self.progressDialog(5000)
  218.  
    self.textBrowser.append("上传文件成功,文件路径:" filePath "/" os.path.basename(pathFile))
  219.  
    else:
  220.  
    QMessageBox.information(self.MainWindow, '警告', '未选择文件!',
  221.  
    QMessageBox.Ok | QMessageBox.Close,
  222.  
    QMessageBox.Close)
  223.  
     
  224.  
    elif command == "下载":
  225.  
    if item.parent():
  226.  
    self.ftpOperation.ftpClient.cwd(self.getLocation(item.parent()))
  227.  
    self.textBrowser.append("正在下载文件" filePath)
  228.  
    res=self.ftpOperation.download(item.text(0))
  229.  
    self.textBrowser.append("下载文件成功,文件路径:" res)
  230.  
    def progressDialog(self,elapsed):
  231.  
    dlg = QProgressDialog()
  232.  
    dlg.setWindowTitle('等待......')
  233.  
    dlg.setWindowModality(Qt.WindowModal)
  234.  
    dlg.show()
  235.  
    for val in range(elapsed):
  236.  
    dlg.setValue(val)
  237.  
    QCoreApplication.processEvents()
  238.  
    if dlg.wasCanceled():
  239.  
    break
  240.  
    dlg.setValue(elapsed)
  241.  
     
  242.  
     
  243.  
     
  244.  
     
  245.  
    def getLocation(self, item):
  246.  
    path=item.text(0)
  247.  
    print(path)
  248.  
    if item.parent():
  249.  
    temp = item.parent()
  250.  
    parentPath=temp.text(0)
  251.  
    print(path)
  252.  
    if parentPath=='/':
  253.  
    path=parentPath path
  254.  
    if temp.parent():
  255.  
    path=self.getLocation(temp) "/" path
  256.  
    return path
  257.  
     
  258.  
     
  259.  
     
  260.  
     
  261.  
    if __name__=='__main__':
  262.  
    import sys
  263.  
     
  264.  
    app = QtWidgets.QApplication(sys.argv)
  265.  
    widget = QtWidgets.QMainWindow()
  266.  
    ui = Ui_MainWindow()
  267.  
    ui.setupUi(widget)
  268.  
    widget.show()
  269.  
    sys.exit(app.exec_())
学新通

项目源码下载链接:python,Pyqt5 实现FTP服务器与客户端文件上传,下载;有问题可以直接csdn问我或评论提问

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbjkia
系列文章
更多 icon
同类精品
更多 icon
继续加载