利用Qt實(shí)現(xiàn)FTP服務(wù)器并支持多客戶端登錄
一、效果展示
二、源碼實(shí)現(xiàn)
由于源碼較多,只分享其中一部分
ftpserverwidget.h
#ifndef FTPSERVERWIDGET_H #define FTPSERVERWIDGET_H #include <QWidget> #include <QGridLayout> #include <QHBoxLayout> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include <QToolButton> #include <QFileDialog> #include <QRegularExpression> #include <QRegularExpressionValidator> #include <QMessageBox> #include <QFileInfo> #include <QHostInfo> #include "ftpServer/ftpserver.h" class FtpServerWidget : public QWidget { Q_OBJECT Q_PROPERTY(QString ip READ get_ip WRITE set_ip) Q_PROPERTY(QString port READ get_port WRITE set_port) Q_PROPERTY(QString userName READ get_user_name WRITE set_user_name) Q_PROPERTY(QString password READ get_password WRITE set_password) Q_PROPERTY(QString path READ get_path WRITE set_path) signals: void para_changed(); public: explicit FtpServerWidget(QWidget *parent = nullptr); ~FtpServerWidget(); bool set_ftp_para(QString ip,QString port,QString userName,QString password,QString path); bool ftp_start_server(); bool ftp_stop_server(); QString get_ip(); void set_ip(QString val); QString get_port(); void set_port(QString val); QString get_user_name(); void set_user_name(QString val); QString get_password(); void set_password(QString val); QString get_path(); void set_path(QString val); protected: void showEvent(QShowEvent *event) override; void closeEvent(QCloseEvent *event) override; private: void value_init(); void control_init(); private slots: void btn_click_slot(); void dir_select_slot(const QString &directory); private: QGridLayout *gridLayout; QHBoxLayout *horizontalLayout; QLabel *label; QLineEdit *lineEditIp; QHBoxLayout *horizontalLayout_2; QLabel *label_2; QLineEdit *lineEditPort; QHBoxLayout *horizontalLayout_3; QLabel *label_3; QLineEdit *lineEditUser; QHBoxLayout *horizontalLayout_4; QLabel *label_4; QLineEdit *lineEditPassward; QHBoxLayout *horizontalLayout_6; QLabel *label_6; QLineEdit *lineEditPath; QPushButton *btnSelectPath; QHBoxLayout *horizontalLayout_7; QPushButton *btnCancel; QPushButton *btnConfirm; QFileDialog *dirSelectDlg; QMessageBox *paraMessageBox; QString ftpIp = nullptr; QString ftpPort = nullptr; QString ftpUserName = nullptr; QString ftpPassword = nullptr; QString ftpPath = nullptr; FtpServer *ftpServer = nullptr; }; #endif // FTPSERVERWIDGET_H
ftpserverwidget.cpp
#include "ftpserverwidget.h" FtpServerWidget::FtpServerWidget(QWidget *parent) : QWidget{parent} { this->value_init(); this->control_init(); } FtpServerWidget::~FtpServerWidget() { this->ftp_stop_server(); } void FtpServerWidget::value_init() { this->ftpIp = "127.0.0.1"; } void FtpServerWidget::control_init() { this->resize(450, 330); this->setMinimumSize(QSize(450, 330)); this->setMaximumSize(QSize(500, 380)); this->setWindowTitle(tr("FTP服務(wù)器參數(shù)設(shè)置")); gridLayout = new QGridLayout(); gridLayout->setObjectName(QString::fromUtf8("gridLayout")); horizontalLayout = new QHBoxLayout(); horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); label = new QLabel(); label->setText(tr("服務(wù)器IP:")); label->setObjectName(QString::fromUtf8("label")); label->setAlignment(Qt::AlignCenter); horizontalLayout->addWidget(label); lineEditIp = new QLineEdit(); lineEditIp->setObjectName(QString::fromUtf8("lineEditIp")); horizontalLayout->addWidget(lineEditIp); horizontalLayout->setStretch(0, 1); horizontalLayout->setStretch(1, 4); gridLayout->addLayout(horizontalLayout, 0, 0, 1, 1); horizontalLayout_2 = new QHBoxLayout(); horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); label_2 = new QLabel(); label_2->setText(tr("服務(wù)器端口:")); label_2->setObjectName(QString::fromUtf8("label_2")); label_2->setAlignment(Qt::AlignCenter); horizontalLayout_2->addWidget(label_2); lineEditPort = new QLineEdit(); lineEditPort->setObjectName(QString::fromUtf8("lineEditPort")); horizontalLayout_2->addWidget(lineEditPort); horizontalLayout_2->setStretch(0, 1); horizontalLayout_2->setStretch(1, 4); gridLayout->addLayout(horizontalLayout_2, 1, 0, 1, 1); horizontalLayout_3 = new QHBoxLayout(); horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3")); label_3 = new QLabel(); label_3->setText(tr("用戶名:")); label_3->setObjectName(QString::fromUtf8("label_3")); label_3->setAlignment(Qt::AlignCenter); horizontalLayout_3->addWidget(label_3); lineEditUser = new QLineEdit(); lineEditUser->setObjectName(QString::fromUtf8("lineEditUser")); horizontalLayout_3->addWidget(lineEditUser); horizontalLayout_3->setStretch(0, 1); horizontalLayout_3->setStretch(1, 4); gridLayout->addLayout(horizontalLayout_3, 2, 0, 1, 1); horizontalLayout_4 = new QHBoxLayout(); horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4")); label_4 = new QLabel(); label_4->setText(tr("登錄密碼:")); label_4->setObjectName(QString::fromUtf8("label_4")); label_4->setAlignment(Qt::AlignCenter); horizontalLayout_4->addWidget(label_4); lineEditPassward = new QLineEdit(); lineEditPassward->setObjectName(QString::fromUtf8("lineEditPassward")); horizontalLayout_4->addWidget(lineEditPassward); horizontalLayout_4->setStretch(0, 1); horizontalLayout_4->setStretch(1, 4); gridLayout->addLayout(horizontalLayout_4, 3, 0, 1, 1); horizontalLayout_6 = new QHBoxLayout(); horizontalLayout_6->setObjectName(QString::fromUtf8("horizontalLayout_6")); label_6 = new QLabel(); label_6->setText(tr("文件路徑:")); label_6->setObjectName(QString::fromUtf8("label_6")); label_6->setAlignment(Qt::AlignCenter); horizontalLayout_6->addWidget(label_6); lineEditPath = new QLineEdit(); lineEditPath->setObjectName(QString::fromUtf8("lineEditPath")); QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(lineEditPath->sizePolicy().hasHeightForWidth()); lineEditPath->setSizePolicy(sizePolicy); horizontalLayout_6->addWidget(lineEditPath); btnSelectPath = new QPushButton(); btnSelectPath->setText(tr("...")); btnSelectPath->setObjectName(QString::fromUtf8("toolBtnSelectPath")); btnSelectPath->setMinimumSize(QSize(82, 0)); horizontalLayout_6->addWidget(btnSelectPath); horizontalLayout_6->setStretch(0, 1); horizontalLayout_6->setStretch(1, 3); horizontalLayout_6->setStretch(2, 1); gridLayout->addLayout(horizontalLayout_6, 4, 0, 1, 1); horizontalLayout_7 = new QHBoxLayout(); horizontalLayout_7->setObjectName(QString::fromUtf8("horizontalLayout_7")); btnCancel = new QPushButton(); btnCancel->setText(tr("取消")); btnCancel->setObjectName(QString::fromUtf8("btnCancel")); QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Fixed); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); sizePolicy1.setHeightForWidth(btnCancel->sizePolicy().hasHeightForWidth()); btnCancel->setSizePolicy(sizePolicy1); btnCancel->setMinimumSize(QSize(0, 50)); horizontalLayout_7->addWidget(btnCancel); btnConfirm = new QPushButton(); btnConfirm->setText(tr("確定")); btnConfirm->setObjectName(QString::fromUtf8("btnConfirm")); sizePolicy1.setHeightForWidth(btnConfirm->sizePolicy().hasHeightForWidth()); btnConfirm->setSizePolicy(sizePolicy1); btnConfirm->setMinimumSize(QSize(0, 50)); horizontalLayout_7->addWidget(btnConfirm); gridLayout->addLayout(horizontalLayout_7, 5, 0, 1, 1); this->setLayout(gridLayout); //限制lineedit格式輸入 QRegularExpression regIpStr("(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])"); QValidator * validator = new QRegularExpressionValidator(regIpStr, this->lineEditIp); this->lineEditIp->setValidator(validator); this->lineEditPort->setValidator(new QIntValidator(0,65535,this->lineEditPort)); QRegularExpression regUserStr("[a-zA-Z0-9]+$"); validator = new QRegularExpressionValidator(regUserStr, this->lineEditUser); this->lineEditUser->setValidator(validator); this->lineEditPassward->setValidator(validator); this->lineEditUser->setMaxLength(8); this->lineEditPassward->setMaxLength(8); this->lineEditIp->setPlaceholderText(tr("請(qǐng)輸入服務(wù)器IP地址!")); this->lineEditPort->setPlaceholderText(tr("請(qǐng)輸入服務(wù)器端口!")); this->lineEditUser->setPlaceholderText(tr("請(qǐng)輸入登錄用戶名!")); this->lineEditPassward->setPlaceholderText(tr("請(qǐng)輸入登錄密碼!")); this->lineEditPath->setPlaceholderText(tr("請(qǐng)輸入文件路徑!")); this->lineEditIp->setStyleSheet("border:2px groove gray;border-radius:8px;padding:2px 4px;border-style: outset;"); this->lineEditPort->setStyleSheet("border:2px groove gray;border-radius:8px;padding:2px 4px;border-style: outset;"); this->lineEditUser->setStyleSheet("border:2px groove gray;border-radius:8px;padding:2px 4px;border-style: outset;"); this->lineEditPassward->setStyleSheet("border:2px groove gray;border-radius:8px;padding:2px 4px;border-style: outset;"); this->lineEditPath->setStyleSheet("border:2px groove gray;border-radius:8px;padding:2px 4px;border-style: outset;"); this->lineEditIp->setReadOnly(true); //路徑選擇dialog初始化 this->dirSelectDlg = new QFileDialog(this); this->dirSelectDlg->setFileMode(QFileDialog::Directory); this->dirSelectDlg->setWindowTitle(tr("請(qǐng)選擇一個(gè)文件夾!")); this->dirSelectDlg->setModal(false); this->dirSelectDlg->close(); connect(this->dirSelectDlg,&QFileDialog::fileSelected,this,&FtpServerWidget::dir_select_slot); //錯(cuò)誤提示messagebox初始化 this->paraMessageBox = new QMessageBox(this); this->paraMessageBox->setModal(false); this->paraMessageBox->setWindowTitle(tr("參數(shù)錯(cuò)誤!")); this->paraMessageBox->setIcon(QMessageBox::Warning); this->paraMessageBox->setMinimumSize(500,100); this->paraMessageBox->close(); connect(this->btnConfirm,&QPushButton::clicked,this,&FtpServerWidget::btn_click_slot); connect(this->btnCancel,&QPushButton::clicked,this,&FtpServerWidget::btn_click_slot); connect(this->btnSelectPath,&QPushButton::clicked,this,&FtpServerWidget::btn_click_slot); } bool FtpServerWidget::set_ftp_para(QString ip, QString port, QString userName, QString password, QString path) { qDebug()<<"ip:"<<ip<<" port:"<<port<<" userName:"<<userName<<" password:"<<password<<" path:"<<path; if(ip == nullptr) { this->paraMessageBox->setText(tr("IP不能為空!")); this->paraMessageBox->show(); return false; } if(port == nullptr) { this->paraMessageBox->setText(tr("端口設(shè)置不能為空!")); this->paraMessageBox->show(); return false; } if(port.toUInt() >65535) { this->paraMessageBox->setText(tr("端口值設(shè)置錯(cuò)誤!")); this->paraMessageBox->show(); return false; } if(userName == nullptr) { this->paraMessageBox->setText(tr("用戶名不能為空!")); this->paraMessageBox->show(); return false; } if(password == nullptr) { this->paraMessageBox->setText(tr("用戶密碼不能為空!")); this->paraMessageBox->show(); return false; } if(path == nullptr) { this->paraMessageBox->setText(tr("路徑不能為空!")); this->paraMessageBox->show(); return false; } QFileInfo info(path); if(!info.exists()) { this->paraMessageBox->setText(tr("路徑不存在!")); this->paraMessageBox->show(); return false; } this->ftpIp = ip; this->ftpPort = port; this->ftpUserName = userName; this->ftpPassword = password; this->ftpPath = path; return true; } bool FtpServerWidget::ftp_start_server() { if(this->ftpIp == nullptr) { return false; } if(this->ftpPort == nullptr) { return false; } if(this->ftpPort.toUInt() >65535) { return false; } if(this->ftpUserName == nullptr) { return false; } if(this->ftpPassword == nullptr) { return false; } if(this->ftpPath == nullptr) { return false; } QFileInfo info(this->ftpPath); if(!info.exists()) { return false; } if (this->ftpServer !=nullptr) { qDebug() << "服務(wù)器已經(jīng)啟動(dòng)"; return true; } this->ftpServer = new FtpServer(this, this->ftpPath, this->ftpPort.toInt(), this->ftpUserName, this->ftpPassword); //connect(m_server, SIGNAL(newPeerIp(QString)), this, SLOT(onNewPeerIp(QString))); qDebug() << "服務(wù)器已啟動(dòng)"; return true; } bool FtpServerWidget::ftp_stop_server() { if(this->ftpServer != nullptr) { delete this->ftpServer; this->ftpServer = NULL; } qDebug() << "服務(wù)器已關(guān)閉"; return true; } QString FtpServerWidget::get_ip() { return this->ftpIp; } void FtpServerWidget::set_ip(QString val) { this->ftpIp = val; emit para_changed(); } QString FtpServerWidget::get_port() { return this->ftpPort; } void FtpServerWidget::set_port(QString val) { this->ftpPort = val; emit para_changed(); } QString FtpServerWidget::get_user_name() { return this->ftpUserName; } void FtpServerWidget::set_user_name(QString val) { this->ftpUserName = val; emit para_changed(); } QString FtpServerWidget::get_password() { return this->ftpPassword; } void FtpServerWidget::set_password(QString val) { this->ftpPassword = val; emit para_changed(); } QString FtpServerWidget::get_path() { return this->ftpPath; } void FtpServerWidget::set_path(QString val) { this->ftpPath = val; emit para_changed(); } void FtpServerWidget::btn_click_slot() { QPushButton *btn = qobject_cast<QPushButton *>(sender()); if(btn == this->btnConfirm) //確定 { QString ipStr = this->lineEditIp->text(); QString portStr = this->lineEditPort->text(); QString userStr = this->lineEditUser->text(); QString passwordStr = this->lineEditPassward->text(); QString pathStr = this->lineEditPath->text(); this->set_ftp_para(ipStr,portStr,userStr,passwordStr,pathStr); this->ftp_start_server(); } else if(btn == this->btnCancel) //取消 { this->close(); } else if(btn == this->btnSelectPath) //選擇路徑 { this->dirSelectDlg->show(); } } void FtpServerWidget::dir_select_slot(const QString &directory) { this->lineEditPath->setText(directory); } void FtpServerWidget::showEvent(QShowEvent *event) { Q_UNUSED(event); if(this->ftpIp != nullptr) { this->lineEditIp->setText(this->ftpIp); } if(this->ftpPort != nullptr) { this->lineEditPort->setText(this->ftpPort); } if(this->ftpUserName !=nullptr) { this->lineEditUser->setText(this->ftpUserName); } if(this->ftpPassword != nullptr) { this->lineEditPassward->setText(this->ftpPassword); } if(this->ftpPath != nullptr) { this->lineEditPath->setText(this->ftpPath); } } void FtpServerWidget::closeEvent(QCloseEvent *event) { Q_UNUSED(event); this->dirSelectDlg->close(); this->paraMessageBox->close(); }
到此這篇關(guān)于利用Qt實(shí)現(xiàn)FTP服務(wù)器并支持多客戶端登錄的文章就介紹到這了,更多相關(guān)Qt FTP服務(wù)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++ throw關(guān)鍵字實(shí)現(xiàn)拋出異常和異常規(guī)范
本文主要介紹了C++ throw關(guān)鍵字實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08C語(yǔ)言編程之動(dòng)態(tài)內(nèi)存與柔性數(shù)組的了解
本文是C語(yǔ)言編程篇,這篇文章主要為大家介紹了C語(yǔ)言編程中動(dòng)態(tài)內(nèi)存的函數(shù)與柔性數(shù)組的特點(diǎn),有需要的朋友可以借鑒參考下,希望可以有所幫助2021-09-09vs2022項(xiàng)目文件夾內(nèi).vs文件夾容量虛高問(wèn)題的解決
經(jīng)常會(huì)發(fā)現(xiàn)VS的項(xiàng)目文件夾占用空間很大,本文主要介紹了vs2022項(xiàng)目文件夾內(nèi).vs文件夾容量虛高問(wèn)題的解決,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09C++構(gòu)造函數(shù)初始化列表的實(shí)現(xiàn)詳解
構(gòu)造函數(shù)主要作用在于創(chuàng)建對(duì)象時(shí)為對(duì)象的成員屬性賦值,構(gòu)造函數(shù)由編譯器自動(dòng)調(diào)用,無(wú)須手動(dòng)調(diào)用;析構(gòu)函數(shù)主要作用在于對(duì)象銷毀前系統(tǒng)自動(dòng)調(diào)用,執(zhí)行一 些清理工作2022-09-09