赞
踩
ftp协议即文件传输协议,人生苦短,我用python,对于编程新手写个ftp服务器及客户端,python绝对是很好的选择,本人用python pyftpdlib模块编写了ftp服务器,也使用pyqt5编写了简单的FTP客户端实现ftp服务器链接文件上传,下载等功能。
1.链接FTP服务器
填写ftp服务器链接主机ip地址,用户名,密码,端口号,点击链接按钮,看到打印链接成功信息及成功链接上ftp服务器,可在下方查看ftp服务器文件。
2.上传文件到FTP服务器
右击链接FTP服务器的文件点击上传按钮,可选择要上传的文件
选择要上传的文件:
看到如下图打印上传文件成功信息,即文件成功上传到Ftp服务器,上传成功后可以在下方Ftp服务器的文件夹中看到上传的文件。
3.下载文件到本地
右击链接FTP服务器的文件点击下载按钮:
看到如下图打印下载文件成功信息,即文件成功从Ftp服务器下载到本地,可以在本地打开下载的文件:
- from pyftpdlib.authorizers import DummyAuthorizer
- from pyftpdlib.handlers import FTPHandler
- from pyftpdlib.servers import FTPServer
-
- class FtpServer:
-
- def ftpStart(self):
- # 实例化虚拟用户,这是FTP验证首要条件
- authorizer = DummyAuthorizer()
-
- authorizer.add_user('user', '12345', 'D:/ftpFile', perm='elradfmw')
- # 添加匿名用户 只需要路径
- authorizer.add_anonymous('D:/ftpFile/test')
-
- handler = FTPHandler
- handler.authorizer = authorizer
- # 添加被动端口范围
- handler.passive_ports = range(2000, 8333)
- # 监听ip 和 端口,使用21端口
- server = FTPServer(('127.0.0.1', 21), handler)
- # server.set_pasv(False)
- # 开始服务
- server.serve_forever()

- # -*- coding: utf-8 -*-
-
- # Form implementation generated from reading ui file 'FtpGui.ui'
- #
- # Created by: PyQt5 UI code generator 5.15.4
- #
- # WARNING: Any manual changes made to this file will be lost when pyuic5 is
- # run again. Do not edit this file unless you know what you are doing.
- from tqdm import tqdm
- import os
- import sys
- BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
- sys.path.insert(0, BASE_DIR)
- from FtpClientOperation import FtpClient
- from PyQt5.QtGui import QIcon,QCursor
- from PyQt5.QtCore import Qt, QUrl, QCoreApplication
- from PyQt5 import QtCore, QtGui, QtWidgets
- from PyQt5.QtWidgets import QMessageBox, QMenu, QAction, QFileDialog, QProgressBar, QProgressDialog
-
- from utils.StringUtils import isNull,isNotNull
-
- class Ui_MainWindow(object):
- def setupUi(self, MainWindow):
- self.MainWindow = MainWindow
- MainWindow.setObjectName("MainWindow")
- MainWindow.resize(384, 489)
- icon = QtGui.QIcon()
- icon.addPixmap(QtGui.QPixmap("../image/icon/FTP.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- MainWindow.setWindowIcon(icon)
- self.centralwidget = QtWidgets.QWidget(MainWindow)
- self.centralwidget.setObjectName("centralwidget")
- self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
- self.verticalLayout.setObjectName("verticalLayout")
- self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
- self.horizontalLayout_3.setObjectName("horizontalLayout_3")
- self.toolButton = QtWidgets.QToolButton(self.centralwidget)
- icon1 = QtGui.QIcon()
- icon1.addPixmap(QtGui.QPixmap("../image/icon/FTP.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.toolButton.setIcon(icon1)
- self.toolButton.setObjectName("toolButton")
- self.horizontalLayout_3.addWidget(self.toolButton)
- self.verticalLayout.addLayout(self.horizontalLayout_3)
- self.horizontalLayout = QtWidgets.QHBoxLayout()
- self.horizontalLayout.setObjectName("horizontalLayout")
- self.label = QtWidgets.QLabel(self.centralwidget)
- self.label.setObjectName("label")
- self.horizontalLayout.addWidget(self.label)
- self.lineEdit_3 = QtWidgets.QLineEdit(self.centralwidget)
- self.lineEdit_3.setObjectName("lineEdit_3")
- self.horizontalLayout.addWidget(self.lineEdit_3)
- self.label_2 = QtWidgets.QLabel(self.centralwidget)
- self.label_2.setObjectName("label_2")
- self.horizontalLayout.addWidget(self.label_2)
- self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
- self.lineEdit_2.setObjectName("lineEdit_2")
- self.horizontalLayout.addWidget(self.lineEdit_2)
- self.label_3 = QtWidgets.QLabel(self.centralwidget)
- self.label_3.setObjectName("label_3")
- self.horizontalLayout.addWidget(self.label_3)
- self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
- self.lineEdit.setObjectName("lineEdit")
- self.horizontalLayout.addWidget(self.lineEdit)
- self.label_4 = QtWidgets.QLabel(self.centralwidget)
- self.label_4.setObjectName("label_4")
- self.horizontalLayout.addWidget(self.label_4)
- self.lineEdit_4 = QtWidgets.QLineEdit(self.centralwidget)
- self.lineEdit_4.setObjectName("lineEdit_4")
- self.horizontalLayout.addWidget(self.lineEdit_4)
- self.pushButton = QtWidgets.QPushButton(self.centralwidget)
- self.pushButton.setObjectName("pushButton")
- self.horizontalLayout.addWidget(self.pushButton)
- self.verticalLayout.addLayout(self.horizontalLayout)
- self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
- self.textBrowser.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
- self.textBrowser.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
- self.textBrowser.setLineWrapMode(0)
- self.textBrowser.setObjectName("textBrowser")
- self.verticalLayout.addWidget(self.textBrowser)
- self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
- self.horizontalLayout_2.setObjectName("horizontalLayout_2")
- self.label_5 = QtWidgets.QLabel(self.centralwidget)
- self.label_5.setObjectName("label_5")
- self.horizontalLayout_2.addWidget(self.label_5)
- self.lineEdit_5 = QtWidgets.QLineEdit(self.centralwidget)
- self.lineEdit_5.setObjectName("lineEdit_5")
- self.horizontalLayout_2.addWidget(self.lineEdit_5)
- self.verticalLayout.addLayout(self.horizontalLayout_2)
- self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
- self.horizontalLayout_4.setObjectName("horizontalLayout_4")
- self.treeWidget = QtWidgets.QTreeWidget(self.centralwidget)
- self.treeWidget.setColumnCount(4)
- self.treeWidget.setObjectName("treeWidget")
- item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
- self.horizontalLayout_4.addWidget(self.treeWidget)
- self.verticalLayout.addLayout(self.horizontalLayout_4)
- MainWindow.setCentralWidget(self.centralwidget)
- self.statusbar = QtWidgets.QStatusBar(MainWindow)
- self.statusbar.setObjectName("statusbar")
- MainWindow.setStatusBar(self.statusbar)
-
- self.retranslateUi(MainWindow)
- self.pushButton.clicked.connect(self.connectFtp)
- self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu) # 打开右键菜单的策略
- self.treeWidget.customContextMenuRequested.connect(self.treeWidgetItem_fun) # 绑定事件
- QtCore.QMetaObject.connectSlotsByName(MainWindow)
-
- def retranslateUi(self, MainWindow):
- _translate = QtCore.QCoreApplication.translate
- MainWindow.setWindowTitle(_translate("MainWindow", "FTP Client"))
- self.toolButton.setText(_translate("MainWindow", "file"))
- self.label.setText(_translate("MainWindow", "主机:"))
- self.label_2.setText(_translate("MainWindow", "用户名:"))
- self.label_3.setText(_translate("MainWindow", "密码:"))
- self.label_4.setText(_translate("MainWindow", "端口号:"))
- self.lineEdit_3.setText(_translate("MainWindow", "127.0.0.1"))
- self.lineEdit_2.setText(_translate("MainWindow", "user"))
- self.lineEdit.setText(_translate("MainWindow", "12345"))
- self.lineEdit.setEchoMode(QtWidgets.QLineEdit.Password)
- self.lineEdit_4.setText(_translate("MainWindow", "21"))
- self.pushButton.setText(_translate("MainWindow", "链接"))
- self.label_5.setText(_translate("MainWindow", "链接远程站点:"))
- self.treeWidget.headerItem().setText(0, _translate("MainWindow", "文件名"))
- self.treeWidget.headerItem().setText(1, _translate("MainWindow", "文件大小"))
- self.treeWidget.headerItem().setText(2, _translate("MainWindow", "文件类型"))
- self.treeWidget.headerItem().setText(3, _translate("MainWindow", "最新修改时间"))
- __sortingEnabled = self.treeWidget.isSortingEnabled()
- self.treeWidget.setSortingEnabled(False)
- self.treeWidget.topLevelItem(0).setText(0, _translate("MainWindow", "/"))
- self.treeWidget.topLevelItem(0).setText(2, _translate("MainWindow", "directory"))
- self.treeWidget.topLevelItem(0).setIcon(0, QIcon('../image/icon/folder.png'))
- self.treeWidget.setSortingEnabled(__sortingEnabled)
- def connectFtp(self):
- addr=self.lineEdit_3.text();
- userName=self.lineEdit_2.text();
- password=self.lineEdit.text();
- port=self.lineEdit.text()
- print("哈哈"+addr+","+userName+","+password)
- if isNull(addr)==True or isNull(userName)==True or isNull(password)==True:
- QMessageBox.information(self.MainWindow, '警告', 'ftp ip地址或用户名或密码不能为空,请检查!', QMessageBox.Ok | QMessageBox.Close,
- QMessageBox.Close)
- else:
- self.ftpOperation=FtpClient(addr,int(port))
- ftpclient=self.ftpOperation.ftp_connect(userName,password)
- print("ftp:"+ftpclient.getwelcome())
- self.textBrowser.append(ftpclient.getwelcome())
- self.textBrowser.append("ftp:"+addr+" 链接成功!")
- ftpPath=ftpclient.pwd()
- self.lineEdit_5.setText(ftpPath)
- _translate = QtCore.QCoreApplication.translate
- print(ftpPath)
- self.treeWidget.topLevelItem(0).setText(0, _translate("MainWindow", ftpPath))
-
- top_file_list=ftpclient.getdirs(ftpPath)
- for i in range(len(top_file_list)):
- self.treeWidget.topLevelItem(0).addChild(QtWidgets.QTreeWidgetItem())
- #['20221104135530', 'perm=radfw', 'size=53990', 'type=file']
- self.treeWidget.topLevelItem(0).child(i).setText(0, _translate("MainWindow", top_file_list[i]))
- modify_time = ftpclient.get_modify_time(ftpPath+top_file_list[i]).split(";")
- self.treeWidget.topLevelItem(0).child(i).setText(1, _translate("MainWindow", modify_time[2][5:-1]))
- self.treeWidget.topLevelItem(0).child(i).setText(3, _translate("MainWindow", modify_time[0]))
- if ftpclient.checkFileDir(ftpPath+top_file_list[i]) == "Dir":
- self.treeWidget.topLevelItem(0).child(i).setText(2, _translate("MainWindow", "directory"))
- self.treeWidget.topLevelItem(0).child(i).setIcon(0, QIcon('../image/icon/folder.png'))
- self.addTreeItem(ftpclient, ftpPath + top_file_list[i], self.treeWidget.topLevelItem(0).child(i),
- _translate)
- else:
- self.treeWidget.topLevelItem(0).child(i).setIcon(0,QIcon('../image/icon/file.png'))
- self.treeWidget.topLevelItem(0).child(i).setText(2, _translate("MainWindow", "file"))
-
- print(top_file_list)
- def addTreeItem(self,ftpclient,filePath,parentItem,_translate):
- file_list = ftpclient.getdirs(filePath)
- for i in range(len(file_list)):
- parentItem.addChild(QtWidgets.QTreeWidgetItem())
- parentItem.child(i).setText(0, _translate("MainWindow", file_list[i]))
- modify_time = ftpclient.get_modify_time(filePath + "/" + file_list[i]).split(";")
- parentItem.child(i).setText(1, _translate("MainWindow", modify_time[2][5:-1]))
- parentItem.child(i).setText(3, _translate("MainWindow", modify_time[0]))
- if ftpclient.checkFileDir(filePath+"/"+file_list[i]) == "Dir":
- parentItem.child(i).setIcon(0, QIcon('../image/icon/folder.png'))
- parentItem.child(i).setText(2,_translate("MainWindow", "directory" ))
- self.addTreeItem(ftpclient, filePath +"/"+ file_list[i], parentItem.child(i),
- _translate)
- else:
- parentItem.child(i).setIcon(0, QIcon('../image/icon/file.png'))
- parentItem.child(i).setText(2, _translate("MainWindow", "file"))
-
- # 定义treewidget中item右键界面
- def treeWidgetItem_fun(self, pos):
- item = self.treeWidget.currentItem()
- item1 = self.treeWidget.itemAt(pos)
-
- if item != None and item1 != None: # 判断菜单是否为空
- popMenu = QMenu()
- if item.text(2)=="directory":
- self.upload=popMenu.addAction(QAction(u'上传', self.treeWidget))
- else:
- self.download=popMenu.addAction(QAction(u'下载', self.treeWidget))
- popMenu.triggered[QAction].connect(self.processtrigger) # 右键点击清空之后执行的操作
- popMenu.exec_(QCursor.pos()) # 执行之后菜单可以显示
-
- # 右键点击清空之后执行的操作
- def processtrigger(self, q):
- # 相应的处理
- command = q.text()
- item = self.treeWidget.currentItem()
- filePath=self.getLocation(item)
- print(filePath)
- if command == "上传":
- self.ftpOperation.ftpClient.cwd(filePath)
- fileUrl = QFileDialog.getOpenFileUrl(None, '打开文件', QUrl('.'),'所有文件(*.*);;Python文件(*.py);;图片(*.png *.jpg)')
- if fileUrl[0]!=None and isNotNull(fileUrl[0].path()):
- pathFile=fileUrl[0].path().strip("/")
- self.textBrowser.append("上传文件:"+pathFile)
- self.textBrowser.append("正在上传文件:" +pathFile+ " 到" + filePath)
- res=self.ftpOperation.upload(pathFile)
- self.progressDialog(5000)
- self.textBrowser.append("上传文件成功,文件路径:" + filePath+"/"+os.path.basename(pathFile))
- else:
- QMessageBox.information(self.MainWindow, '警告', '未选择文件!',
- QMessageBox.Ok | QMessageBox.Close,
- QMessageBox.Close)
-
- elif command == "下载":
- if item.parent():
- self.ftpOperation.ftpClient.cwd(self.getLocation(item.parent()))
- self.textBrowser.append("正在下载文件" + filePath)
- res=self.ftpOperation.download(item.text(0))
- self.textBrowser.append("下载文件成功,文件路径:" + res)
- def progressDialog(self,elapsed):
- dlg = QProgressDialog()
- dlg.setWindowTitle('等待......')
- dlg.setWindowModality(Qt.WindowModal)
- dlg.show()
- for val in range(elapsed):
- dlg.setValue(val)
- QCoreApplication.processEvents()
- if dlg.wasCanceled():
- break
- dlg.setValue(elapsed)
-
-
-
-
- def getLocation(self, item):
- path=item.text(0)
- print(path)
- if item.parent():
- temp = item.parent()
- parentPath=temp.text(0)
- print(path)
- if parentPath=='/':
- path=parentPath+path
- if temp.parent():
- path=self.getLocation(temp)+"/"+path
- return path
-
-
-
-
- if __name__=='__main__':
- import sys
-
- app = QtWidgets.QApplication(sys.argv)
- widget = QtWidgets.QMainWindow()
- ui = Ui_MainWindow()
- ui.setupUi(widget)
- widget.show()
- sys.exit(app.exec_())

项目源码下载链接:python,Pyqt5 实现FTP服务器与客户端文件上传,下载;有问题可以直接csdn问我或评论提问
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。