Skip to content

FTP工具

1 两台电脑通过网线建立本地连接,保证网关在同一段;

2 服务器端打开ftp;

控制面板→程序→启用或关闭windows功能→windows功能→Internet信息服务
启用“FTP服务”FTP扩展性” IIS管理控制台”

开始屏幕的搜索中输入“IIS”,然后点击打开“IIS管理器”
打开“IIS管理器”后,在左栏的“网站”上点击右键,打开“添加FTP站点”
然后按照提示填写站点信息
点击“下一步”,按照下图提示,设置“绑定和SSL设置”,在“IP地址”处,可以用内网IP也可以用外网IP,访客自然也就根据你的IP设定来决定;
点击“下一步”,设置“身份验证和授权信息”
然后在本机浏览器地址栏中输入“ftp://填写的IP”测试一下

3 客户端网页测试远程访问;

客户端(另一台电脑)浏览器地址栏中输入“ftp://填写的IP”测试一下

4 客户端cmd测试远程访问;

win+r打开运行窗口,输入cmd
回车打开cmd命令窗口
cmd命令中输入:ftp回车
回车切换至ftp命令窗口,输入命令:open,回车提示:到
到即所要连接测试的ftp地址,我们输入:IP 22
即:ip地址+空格+端口号,没有+号
回车后弹出用户一行,输入ftp的用户名后回车,输入ftp用户名对应的密码
输入密码后回车,如果提示,user logged in就说么ftp创建无问题

5 客户端程序测试远程访问。

新建程序,添加ftpclass.cpp、ftpclass.h,复制main.cpp内容到程序入口函数
注意:/项目-属性-常规-字符集-使用多字节字符集/

//main.cpp
#include "stdafx.h"
#include "ftpclass.h"

void main()
{
    printf("------- 开始测试!------\n");
    printf("01--创建连接 %d\n", FtpClass::createConnection());
    printf("02--打开目标ftp %d\n", FtpClass::createTable());    

    /*可以读取ini内参数
    FtpClass::ftp_Ip = TEXT("Ini读取");
    FtpClass::ftp_Port = TEXT("Ini读取");
    FtpClass::ftp_User = TEXT("Ini读取");
    FtpClass::ftp_Password = TEXT("Ini读取");
    FtpClass::ftp_Fixed_Path = TEXT("Ini读取");*/

    printf("03--创建文件夹 %d\n", FtpClass::createFolder("自动生成目录1","自动生成目录2","自动生成目录3"));    
    /*上传目标路径*/

    printf("04--上传文件 %d\n", FtpClass::insert( "D:/a.txt", "b.txt"));
    /*本机文件需要上传文件*/  /*上传后文件名称,可以和本地文件名称不一样,类型最好别换*/

    printf("05--关闭通讯 %d\n", FtpClass::createClose());
    printf("------ 结束测试!------\n");

    return ;
}
//ftpclass.h
/*项目-属性-常规-字符集-使用多字节字符集*/
/*wininet.lib、shlwapi.lib可以直接添加到附加依赖项*/
/*BOOL_VERIFY、NULL_VERIFY 程序结束判断*/


#pragma once

#pragma comment(lib,"wininet.lib")
#pragma comment(lib,"shlwapi.lib")

#define  BOOL_VERIFY(emStatus_bool,switch_bool) \
if (emStatus_bool == true)\
{return true;}\
else{\
if (switch_bool == 3) printf("      FTP_03_err:创建文件夹失败!%d\n"); \
if (switch_bool == 4) printf("      FTP_04_err:上传文件失败!\n");     \
if (switch_bool == 5) printf("      FTP_05_err:关闭窗口句柄失败!\n"); \
return false;\
}


#define  NULL_VERIFY(emStatus_null,switch_null) \
if (emStatus_null != NULL)\
{return true;}\
else{\
if (switch_null == 1) {printf("      FTP_01_err:打开通讯错误 Error:%d\n", GetLastError());}\
if (switch_null == 2) {printf("      FTP_02_err:建立连接错误 Error:%d\n", GetLastError());}\
return false;\
}


#include "stdafx.h"//没用
#include <afxinet.h>//MFC相关
#include "wininet.h"//调用FTP相关类
#include "shlwapi.h"//调用文件操作相关类


class FtpClass
{
public: 
    /*ini读取变量*/
    static CString ftp_Ip;//目标ip
    static CString ftp_Port;//目标端口
    static CString ftp_User;//目标账户
    static CString ftp_Password;//目标密码
    static CString ftp_Fixed_Path;//目标固定路径
    static CString ftp_Free_Path;//目标自己生成路径

     /*全局变量*/
    static BOOL  pRes;
    static HINTERNET hInternet;
    static HINTERNET hConnect;

    /*全局函数*/
    static bool createConnection();                                         //创建一个连接
    static bool createTable();  
    static bool ThreadInternetConnect(PVOID ) 
    //打开目标ftp
    static bool createFolder(CString temp1, CString temp2, CString temp3);  //上传文件
    static bool insert(CString temp, CString temp1);                        //出入数据
    static bool createClose();                                              //断开连接
};
//ftpclass.cpp
#include "stdafx.h"
#include "ftpclass.h"



CString FtpClass::ftp_Ip = TEXT("192.168.3.104");
CString FtpClass::ftp_Port = TEXT("21");
CString FtpClass::ftp_User = TEXT("Administrator");
CString FtpClass::ftp_Password = TEXT("xinxin");
CString FtpClass::ftp_Fixed_Path = TEXT("1级固定目录/2级固定目录/3级固定目录");
CString FtpClass::ftp_Free_Path = TEXT("自动生成目录");
BOOL  FtpClass::pRes = false;
HINTERNET FtpClass::hInternet = NULL;
HINTERNET FtpClass::hConnect = NULL;


//创建一个连接
bool FtpClass::createConnection() {
    /*ftp_Ip = TEXT("Ini读取");
    ftp_Port = TEXT("Ini读取");
    ftp_User = TEXT("Ini读取");
    ftp_Password = TEXT("Ini读取");
    ftp_Fixed_Path = TEXT("Ini读取");*/

    hInternet = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT,
        NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE);
    NULL_VERIFY(hInternet,1);
}
bool FtpClass::ThreadInternetConnect(PVOID param) {

 // 打开http      
 hConnect = InternetConnect(hInternet, ftp_Ip, INTERNET_DEFAULT_FTP_PORT,//INTERNET_DEFAULT_FTP_PORT  第三个参数默认值21
  ftp_User, ftp_Password, INTERNET_SERVICE_FTP,
  INTERNET_FLAG_EXISTING_CONNECT || INTERNET_FLAG_PASSIVE, 0);

 return 1;
}

//打开目标ftp
bool FtpClass::createTable()
{
 /*hConnect = InternetConnect(hInternet, ftp_Ip, 25,//INTERNET_DEFAULT_FTP_PORT  第三个参数默认值21
  ftp_User, ftp_Password, INTERNET_SERVICE_FTP,
  INTERNET_FLAG_EXISTING_CONNECT || INTERNET_FLAG_PASSIVE, 0);
 NULL_VERIFY(hConnect,2);*/
 HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadInternetConnect, (LPVOID)NULL, 0, NULL); 
 //超时3秒,如果等待结果是超时
 if (WaitForSingleObject(hThread, 3 * 1000) == WAIT_TIMEOUT) {
  TerminateThread(hThread, 0);
  CloseHandle(hThread);
  NULL_VERIFY(hConnect, 2);  
 }
 NULL_VERIFY(hConnect, 2);
}

//上传文件
bool FtpClass::createFolder(CString temp1, CString temp2, CString temp3)
{
    /*新建文件件每次只能创建一级,多个需要分多次创建*/
    pRes = false;   
    ftp_Free_Path = "";
    ftp_Free_Path = ftp_Fixed_Path  + "/" + temp1;
    FtpCreateDirectory(hConnect, ftp_Free_Path);
    ftp_Free_Path = ftp_Free_Path + "/" + temp2;
    FtpCreateDirectory(hConnect, ftp_Free_Path);
    ftp_Free_Path = ftp_Free_Path + "/" + temp3;
    pRes = FtpCreateDirectory(hConnect, ftp_Free_Path);
    BOOL_VERIFY(pRes,3);
}
//出入数据
bool FtpClass::insert(CString temp, CString temp1)
{
    pRes = false;
    ftp_Free_Path = ftp_Free_Path + "/" +temp1;
    pRes = FtpPutFile(hConnect, temp,/*本机文件*/
        ftp_Free_Path,  /*TEXT("一级目录/二级目录/三级目录/a.txt"),*/
        FTP_TRANSFER_TYPE_ASCII, 0);
    BOOL_VERIFY(pRes,4);
}
//断开连接
bool FtpClass::createClose()
{   
    pRes = false;
    if (InternetCloseHandle(hConnect))
        pRes = InternetCloseHandle(hInternet);
    BOOL_VERIFY(pRes,5);
}
#ifndef FORMCONNECT_H
#define FORMCONNECT_H

#include <QWidget>
#include <QUrl>
#include <QFile>
#include <QNetworkReply>
#include <QNetworkAccessManager>


namespace Ui {
class FormConnect;
}


class FtpManager : public QObject {
    Q_OBJECT

  public:
    explicit FtpManager(QObject *parent = nullptr);
    // 设置地址和端口
    void setHostPort(const QString &host, int port = 21);
    // 设置登录 FTP 服务器的用户名和密码
    void setUserInfo(const QString &userName, const QString &password);
    // 上传文件
    void put(const QString &fileName, const QString &path);
    // 下载文件
    void get(const QString &path, const QString &fileName);
  signals:
    void error(QNetworkReply::NetworkError);
    // 上传进度
    void uploadProgress(qint64 bytesSent, qint64 bytesTotal);
    // 下载进度
    void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);


  private slots:
    // 下载过程中写文件
    void finished();

  private:
    QUrl m_pUrl_;
    QFile m_file_;
    QNetworkAccessManager m_manager_;
};


class FormConnect : public QWidget {
    Q_OBJECT

  public:
    explicit FormConnect(QWidget *parent = nullptr);
    ~FormConnect();
  public slots:
    void upload();
    void UpLoadFile(const int tmp);
    void uploadProgress(qint64 bytesSent, qint64 bytesTotal);
    void error(QNetworkReply::NetworkError error);

  signals:
    void SignalOneFileOkOut(const int tmp);
  private:
    bool FindFile(const QString &path);
    Ui::FormConnect *ui;
    FtpManager m_ftp;
    int nFiles;
    int nFile;
    QStringList blog_file_names_;
    QStringList blog_file_paths_;
};

#endif // FORMCONNECT_H
#include "formconnect.h"
#include "ui_formconnect.h"
#include <QFile>
#include <QFileInfo>
#include <app.h>
#include <QChar>


FormConnect::FormConnect(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FormConnect) {
    ui->setupUi(this);
    // 接信号槽
    connect(ui->pUploadButton, SIGNAL(clicked(bool)), this, SLOT(upload()));
    connect(&m_ftp, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SLOT(error(QNetworkReply::NetworkError)));
    connect(&m_ftp, SIGNAL(uploadProgress(qint64, qint64)),
            this, SLOT(uploadProgress(qint64, qint64)));
    connect(this, &FormConnect::SignalOneFileOkOut,
            this, &FormConnect::UpLoadFile);
    // 设置 FTP 相关信息
    m_ftp.setHostPort("ip", 21);
    m_ftp.setUserInfo("yaoxin", "*****");
    //*****的是我的密码,欢迎访问我的私人网站http://ip/blog-Navigation.html,虽然啥也没有
}

FormConnect::~FormConnect() {
    delete ui;
}



// 上传文件
void FormConnect::upload() {
    ui->pUploadButton->setEnabled(0);
    nFiles = 0;
    nFile = 0;
    blog_file_paths_.clear();
    blog_file_names_.clear();
    FindFile("/home/yx/视频/cloud.arteryflow/Seafile/博客共享/WWW");
    UpLoadFile(nFile);
    ui->label_2->setText(QString("0/%1").arg(nFiles));
    /* 下载文件
    //void FormConnect::download() {
    //    m_ftp.get("blog-image/", "/home/yx/音乐/blog文件/blog-image");
    //    connect(&m_ftp, SIGNAL(error(QNetworkReply::NetworkError)),
    //            this, SLOT(error(QNetworkReply::NetworkError)));
    //    connect(&m_ftp, SIGNAL(downloadProgress(qint64, qint64)),
    //            this, SLOT(downloadProgress(qint64, qint64)));

    //    qDebug() << blog_file_paths_ ;
    //    qDebug() << nFiles ;
    //}
    // 更新下载进度
    //void FormConnect::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
    //   ui->m_pDownloadBar->setMaximum(static_cast<qint32>(bytesReceived));
    //   ui->m_pDownloadBar->setValue(static_cast<qint32>(bytesTotal));
    //}
    // void download();
    //void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);*/
}

void FormConnect::UpLoadFile(const int tmp) {
    if (tmp >= nFiles) {
        ui->pUploadButton->setEnabled(1);
        QUIHelper::showMessageBoxInfo("上传完成");
        ui->label_2->setText("0/0");
        ui->m_pUploadBar->setValue(0);
        return;
    }
    QString local_files = blog_file_paths_.at(tmp) + "/" + blog_file_names_.at(tmp);
    QString remote_files =
        QString(blog_file_paths_.at(tmp))
        .remove("/home/yx/视频/cloud.arteryflow/Seafile/博客共享/WWW") + "/" +
        blog_file_names_.at(tmp);
    qDebug() << local_files << "is OK";
    qDebug() << remote_files << "is OK";
    m_ftp.put(local_files, remote_files);
    ui->label_2->setText(QString("%2/%1").arg(nFiles).arg(tmp));
}



// 更新上传进度
void FormConnect::uploadProgress(qint64 bytesSent, qint64 bytesTotal) {
    ui->m_pUploadBar->setMaximum(static_cast<qint32>(bytesSent));
    ui->m_pUploadBar->setValue(static_cast<qint32>(bytesTotal));

    if (bytesSent == bytesTotal) {
        nFile++;
        emit SignalOneFileOkOut(nFile);
    }

}



// 错误处理
void FormConnect::error(QNetworkReply::NetworkError error) {
    switch (error) {
    case QNetworkReply::HostNotFoundError :
        qDebug() << QString::fromLocal8Bit("主机没有找到");
        break;
    // 其他错误处理
    default:
        break;
    }
}

bool FormConnect::FindFile(const QString &path) {

    QDir dir(path);
    if (!dir.exists()) {
        return false;
    }
    dir.setFilter(QDir::Dirs | QDir::Files);
    dir.setSorting(QDir::DirsFirst);
    QFileInfoList list = dir.entryInfoList();
    int i = 0;
    do {

        QFileInfo fileInfo = list.at(i);
        if (fileInfo.fileName() == "." | fileInfo.fileName() == "..") {
            i++;
            continue;
        }
        bool bisDir = fileInfo.isDir();
        if (bisDir) {
            FindFile(fileInfo.filePath());
        } else {
            blog_file_paths_ << fileInfo.path();
            blog_file_names_ << fileInfo.fileName();
            qDebug() << QString(" %2  %3  ")
                     .arg(fileInfo.path())
                     .arg(fileInfo.fileName());
            nFiles++;
        }
        i++;
    } while (i < list.size());
    return true;
}
FtpManager::FtpManager(QObject *parent)
    : QObject(parent) {
    // 设置协议
    m_pUrl_.setScheme("ftp");
}

// 设置地址和端口
void FtpManager::setHostPort(const QString &host, int port) {
    m_pUrl_.setHost(host);
    m_pUrl_.setPort(port);
}

// 设置登录 FTP 服务器的用户名和密码
void FtpManager::setUserInfo(const QString &userName, const QString &password) {
    m_pUrl_.setUserName(userName);
    m_pUrl_.setPassword(password);
}

// 上传文件
void FtpManager::put(const QString &fileName, const QString &path) {
    QFile file(fileName);
    file.open(QIODevice::ReadOnly);
    QByteArray data = file.readAll();

    m_pUrl_.setPath(path);
    QNetworkReply *pReply = m_manager_.put(QNetworkRequest(m_pUrl_), data);



    connect(pReply, SIGNAL(uploadProgress(qint64, qint64)),
            this, SIGNAL(uploadProgress(qint64, qint64)));
    connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SIGNAL(error(QNetworkReply::NetworkError)));
}

// 下载文件
void FtpManager::get(const QString &path, const QString &fileName) {
    QFileInfo info;
    info.setFile(fileName);

    m_file_.setFileName(fileName);
    m_file_.open(QIODevice::WriteOnly | QIODevice::Append);
    m_pUrl_.setPath(path);

    QNetworkReply *pReply = m_manager_.get(QNetworkRequest(m_pUrl_));

    connect(pReply, SIGNAL(finished()), this, SLOT(finished()));
    connect(pReply, SIGNAL(downloadProgress(qint64, qint64)),
            this, SIGNAL(downloadProgress(qint64, qint64)));
    connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SIGNAL(error(QNetworkReply::NetworkError)));
}

// 下载过程中写文件
void FtpManager::finished() {
    QNetworkReply *pReply = qobject_cast<QNetworkReply *>(sender());
    switch (pReply->error()) {
    case QNetworkReply::NoError : {
        m_file_.write(pReply->readAll());
        m_file_.flush();
    }
    break;
    default:
        break;
    }

    m_file_.close();
    pReply->deleteLater();
}