上篇文章讲到了HTTP协议,这篇文章我们使用FTP协议来登录我的个人网站,在稳重贴出的代码中,这个服务器是随便填的,测试是登录成功的,有一个BUG,就是必须点击两次连接按钮才能够登录成功,可以下载文件,但是没有实现上传文件,大家可以自行去实现,我写博客的目的是为了备忘,在脑海中有一个印象,当在我的实际项目中需要用到这一块知识的时候我在来深入研究,现在只需要有一个大致的印象,方便以后的开发.
有网友反映说我写的文章有点偏基础,这一点我也是承认的.因为我还是学生,现在的目的是补充自己的知识技能拓展自己的视野,等我到实际工作的时候才会朝着某一个方向深入研究,同时会给大家带来更加优质的文章.
新建Qt Gui应用,项目名称是myFTP,其他默认.在工程问价中添加QT += network
mian.cpp
#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
MainWindow w;
w.show();
return a.exec();
}
mianwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFtp>
#include <QTextCodec>
#include <QHash>
class QFtp;
class QFile;
class QUrlInfo;
class QTreeWidgetItem;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QFtp *ftp;
QHash<QString, bool> isDirectory;
QString currentPath;
QFile *file;
private slots:
void ftpCommandStarted(int);
void ftpCommandFinished(int, bool);
void updateDataTransferProgress(qint64, qint64 );
void addToList(const QUrlInfo &urlInfo);
void processItem(QTreeWidgetItem*, int);
void on_connectButton_clicked();
void on_cdToParentButton_clicked();
void on_downloadButton_clicked();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QTreeWidgetItem>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->progressBar->setValue(0);
connect(ui->fileList, SIGNAL(itemActivated(QTreeWidgetItem*, int)),
this, SLOT(processItem(QTreeWidgetItem*, int)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::ftpCommandStarted(int)
{
int id = ftp->currentCommand();
switch (id)
{
case QFtp::ConnectToHost :
ui->label->setText(tr("正在连接服务器..."));
break;
case QFtp::Login :
ui->label->setText(tr("正在登录..."));
break;
case QFtp::Get :
ui->label->setText(tr("正在下载文件..."));
break;
case QFtp::Close :
ui->label->setText(tr("正在关闭连接..."));
}
}
void MainWindow::ftpCommandFinished(int id, bool error)
{
//if(ftp->currentCommand() == QFtp::ConnectToHost)
if(id == QFtp::ConnectToHost)
{
if (error)
ui->label->setText(tr("连接服务器出现错误:%1").arg(ftp->errorString()));
else
ui->label->setText(tr("连接服务器成功"));
}
else if(id == QFtp::Login)
{
if(error)
ui->label->setText(tr("登录出现错误:%1").arg(ftp->errorString()));
else
{
ui->label->setText(tr("登录成功"));
ftp->list();
}
}
else if(id == QFtp::Get)
{
if(error)
ui->label->setText(tr("下载出现错误:%1").arg(ftp->errorString()));
else {
ui->label->setText(tr("下载成功"));
file->close();
}
ui->downloadButton->setEnabled(true);
}
else if(id == QFtp::List)
{
if(isDirectory.isEmpty())
{
ui->fileList->addTopLevelItem(new QTreeWidgetItem(QStringList()<< tr("<empty>")));
ui->fileList->setEnabled(false);
ui->label->setText(tr("该目录为空"));
}
}
else if(id == QFtp::Close)
{
ui->label->setText(tr("已经关闭连接"));
}
}
void MainWindow::on_connectButton_clicked()
{
ui->fileList->clear();
currentPath.clear();
isDirectory.clear();
ftp = new QFtp(this);
connect(ftp, SIGNAL(commandStarted(int)), this, SLOT(ftpCommandStarted(int)));
connect(ftp, SIGNAL(commandFinished(int, bool)),
this, SLOT(ftpCommandFinished(int, bool)));
connect(ftp, SIGNAL(listInfo(QUrlInfo)), this, SLOT(addToList(QUrlInfo)));
connect(ftp, SIGNAL(dataTransferProgress(qint64, qint64)),
this, SLOT(updateDataTransferProgress(qint64, qint64)));
QString ftpServer = ui->ftpServerLineEdit->text();
QString userName = ui->userNameLineEdit->text();
QString passWord = ui->passWordLineEdit->text();
qDebug() << "ftpServer" << ftpServer;
qDebug() << "userName" << userName;
qDebug() << "passWord" << passWord;
ftp->connectToHost(ftpServer, 324);
ftp->login(userName, passWord);
}
void MainWindow::addToList(const QUrlInfo &urlInfo)
{
QTreeWidgetItem *item = new QTreeWidgetItem;
item->setText(0, urlInfo.name());
item->setText(1, QString::number(urlInfo.size()));
item->setText(2, urlInfo.owner());
item->setText(3, urlInfo.group());
item->setText(4, urlInfo.lastModified().toString("MMM dd yyyy"));
QPixmap pixmap(urlInfo.isDir() ? "../myFTP/dir.png" : "../myFTP/file.png");
item->setIcon(0, pixmap);
isDirectory[urlInfo.name()] = urlInfo.isDir();
ui->fileList->addTopLevelItem(item);
if (!ui->fileList->currentItem()) {
ui->fileList->setCurrentItem(ui->fileList->topLevelItem(0));
ui->fileList->setEnabled(true);
}
}
void MainWindow::processItem(QTreeWidgetItem *item, int)
{
QString name = item->text(0);
if (isDirectory.value(name)) {
ui->fileList->clear();
isDirectory.clear();
currentPath += "/";
currentPath += name;
ftp->cd(name);
ftp->list();
ui->cdToParentButton->setEnabled(true);
}
}
void MainWindow::on_cdToParentButton_clicked()
{
ui->fileList->clear();
isDirectory.clear();
currentPath = currentPath.left(currentPath.lastIndexOf('/'));
if (currentPath.isEmpty()) {
ui->cdToParentButton->setEnabled(false);
ftp->cd("/");
} else {
ftp->cd(currentPath);
}
ftp->list();
}
void MainWindow::on_downloadButton_clicked()
{
QString fileName = ui->fileList->currentItem()->text(0);
file = new QFile(fileName);
if (!file->open(QIODevice::WriteOnly)) {
delete file;
return;
}
ui->downloadButton->setEnabled(false);
ftp->get(ui->fileList->currentItem()->text(0), file);
}
void MainWindow::updateDataTransferProgress(qint64 readBytes,qint64 totalBytes)
{
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(readBytes);
}
mainwndow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>510</width>
<height>363</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>290</y>
<width>371</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>FTP客户端</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>FTP服务器:</string>
</property>
</widget>
<widget class="QLineEdit" name="ftpServerLineEdit">
<property name="geometry">
<rect>
<x>80</x>
<y>20</y>
<width>351</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>ftp.6kshknb4wjwvht0qLinux.com</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>54</width>
<height>12</height>
</rect>
</property>
<property name="text">
<string>用户名:</string>
</property>
</widget>
<widget class="QLineEdit" name="userNameLineEdit">
<property name="geometry">
<rect>
<x>80</x>
<y>50</y>
<width>141</width>
<height>20</height>
</rect>
</property>
<property name="toolTip">
<string>默认用户名请使用:anonymous ,此时密码任意。</string>
</property>
<property name="text">
<string>know</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>250</x>
<y>50</y>
<width>54</width>
<height>12</height>
</rect>
</property>
<property name="text">
<string>密码:</string>
</property>
</widget>
<widget class="QLineEdit" name="passWordLineEdit">
<property name="geometry">
<rect>
<x>310</x>
<y>50</y>
<width>121</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>sadasdasdasd</string>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
<widget class="QPushButton" name="connectButton">
<property name="geometry">
<rect>
<x>450</x>
<y>50</y>
<width>51</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>连接</string>
</property>
</widget>
<widget class="QTreeWidget" name="fileList">
<property name="geometry">
<rect>
<x>10</x>
<y>80</y>
<width>491</width>
<height>161</height>
</rect>
</property>
<column>
<property name="text">
<string>文件</string>
</property>
</column>
<column>
<property name="text">
<string>大小</string>
</property>
</column>
<column>
<property name="text">
<string>拥有者</string>
</property>
</column>
<column>
<property name="text">
<string>所属组</string>
</property>
</column>
<column>
<property name="text">
<string>修改日期</string>
</property>
</column>
</widget>
<widget class="QProgressBar" name="progressBar">
<property name="geometry">
<rect>
<x>10</x>
<y>250</y>
<width>391</width>
<height>23</height>
</rect>
</property>
<property name="value">
<number>24</number>
</property>
</widget>
<widget class="QPushButton" name="cdToParentButton">
<property name="geometry">
<rect>
<x>414</x>
<y>250</y>
<width>81</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>返回上级目录</string>
</property>
</widget>
<widget class="QPushButton" name="downloadButton">
<property name="geometry">
<rect>
<x>414</x>
<y>290</y>
<width>81</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>下载</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>510</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
程序运行效果如下:
文章出自:Linux_Google