qt下采用libcurl实现ftp与tftp功能,提供源代码程序

一、FTP简介

      FTP(文件传输协议),工作在应用层,是用于在网络上进行文件传输的一套标准协议。它使用 TCP 传输,客户在和服务器建立连接前要经过一个“三次握手”的过程, 保证客户与服务器之间的连接是可靠的, 而且是面向连接, 为数据传输提供可靠保证。
      FTP 的独特的优势同时也是与其它客户服务器程序最大的不同点就在于它在两台通信的主机之间使用了两条 TCP 连接,一条是数据连接,用于数据传送;另一条是控制连接,用于传送控制信息(命令和响应),这种将命令和数据分开传送的思想大大提高了 FTP 的效率,而其它客户服务器应用程序一般只有一条 TCP 连接。
      FTP的传输有两种方式:ASCII、二进制
      FTP支持两种模式:
            1) Standard (PORT方式,主动方式)
            2) Passive (PASV,被动方式)

二、TFTP简介

      TFTP是一个传输文件的简单协议,它基于UDP协议而实现,提供不复杂、开销不大的文件传输服务,默认端口号69。此协议设计的时候是进行小文件传输的,因此它不具备通常的FTP的许多功能,它只能从文件服务器上获得或写入文件,不能列出目录,不进行认证,它传输8位数据。

三、TFTP与FTP区别

      1.FTP 是完整、面向会话、常规用途文件传输协议。而 TFTP 用作 bones bare - 特殊目的文件传输协议。
      2.交互使用 FTP。 TFTP 允许仅单向传输的文件。
      3.FTP 提供身份验证。而TFTP 不。
      4.FTP 使用已知 TCP 端口号: 20 的数据和 21 用于连接对话框。 TFTP 用于 UDP 端口号 69 其文件传输活动。
      5.FTP 依赖于 TCP,是面向连接并提供可靠的控件。 TFTP 依赖 UDP,需要减少开销, 几乎不提供控件。

四、tftp和ftp服务器的搭建

1.ftp服务器使用WFTPD搭建

下载地址:https://download.csdn.net/download/linyibin_123/87341049

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.tftp服务器使用Tftpd32搭建

下载地址:https://download.csdn.net/download/linyibin_123/87341061

在这里插入图片描述

五、qt下使用libcurl实现tftp和ftp功能

1.界面

在这里插入图片描述

2.核心代码

tftp和ftp可以共享一份代码,只是url不一样而已。

static size_t writeFunc(void *buffer, size_t size, size_t nmemb,
                        void *stream)
{
  struct FtpFile *out = static_cast<struct FtpFile *>(stream);
  if(out && !out->stream)
  {
      errno_t err = fopen_s(&(out->stream), out->filename, "wb");
      if (err)
      {
          MY_DEBUG << "writeFunc fopen_s failed";
          return static_cast<size_t>(-1);
      }
  }
  qDebug()<<"filename:"<<out->filename;
  return fwrite(buffer, size, nmemb, out->stream);
}

size_t getContentLengthFunc(void *ptr, size_t size, size_t nmemb, void *stream)
{
    long len = 0;
    int ret = sscanf_s(static_cast<const char*>(ptr), "Content-Length: %ld\n", &len);
    if (ret)
    {
        *(static_cast<long *>(stream)) = len;
    }
    return size * nmemb;
}

size_t discardFunc(size_t size, size_t nmemb)
{
    return size * nmemb;
}

size_t readFunc(void *ptr, size_t size, size_t nmemb, void *stream)
{
    FILE *f = static_cast<FILE*>(stream);
    size_t n;
    if (ferror(f))
    {
        return CURL_READFUNC_ABORT;
    }
    n = fread(ptr, size, nmemb, f) * size;
    return n;
}

int CurlSdk::DownLoadFtp(const string &strUrl, const string &localfile, long nTimeout)
{

    curl_global_init(CURL_GLOBAL_DEFAULT);
    struct FtpFile ftpfile={
       localfile.c_str(), //name to store the file as if succesful
       nullptr
     };

    CURLcode res;
    CURL* pCurl = curl_easy_init();
    if(nullptr == pCurl)
    {
        return CURLE_FAILED_INIT;
    }

    curl_easy_setopt(pCurl, CURLOPT_URL, strUrl.c_str());
    curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, nTimeout);
    curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, writeFunc);
    curl_easy_setopt(pCurl, CURLOPT_HEADERFUNCTION, getContentLengthFunc);
    curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &ftpfile);
    curl_easy_setopt(pCurl, CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_NOCWD);
    curl_easy_setopt(pCurl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
    curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 1L);

    res = curl_easy_perform(pCurl);
    curl_easy_cleanup(pCurl);

    //close the local file
    if(ftpfile.stream)
        fclose(ftpfile.stream);

    curl_global_cleanup();

    return res;
}

int CurlSdk::UploadFtp(const string& strUrl, const string& localfile, long tries, long nTimeout)
{
    CURLcode res = CURLE_GOT_NOTHING;
    CURL* pCurl = curl_easy_init();
    if(nullptr == pCurl)
    {
        return CURLE_FAILED_INIT;
    }

    FILE *pFile;
    long uploadedLen = 0;
    errno_t err = fopen_s(&pFile, localfile.c_str(), "rb");
    if (err)
    {
        MY_DEBUG << "fopen_s failed";
        return -1;
    }

    curl_easy_setopt(pCurl, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(pCurl, CURLOPT_URL, strUrl.c_str());
    curl_easy_setopt(pCurl, CURLOPT_FTP_RESPONSE_TIMEOUT, nTimeout);
    curl_easy_setopt(pCurl, CURLOPT_HEADERFUNCTION, getContentLengthFunc);
    curl_easy_setopt(pCurl, CURLOPT_HEADERDATA, &uploadedLen);
    curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, discardFunc);
    curl_easy_setopt(pCurl, CURLOPT_READFUNCTION, readFunc);
    curl_easy_setopt(pCurl, CURLOPT_READDATA, pFile);
    curl_easy_setopt(pCurl, CURLOPT_FTPPORT, "-");
    curl_easy_setopt(pCurl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);
    curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 1L);

    for (int i = 0; (res != CURLE_OK) && (i < tries); i++)
    {
        if (i)
        {
            curl_easy_setopt(pCurl, CURLOPT_NOBODY, 1L);
            curl_easy_setopt(pCurl, CURLOPT_HEADER, 1L);
            res = curl_easy_perform(pCurl);
            if (res != CURLE_OK)
            {
                continue;
            }
            curl_easy_setopt(pCurl, CURLOPT_NOBODY, 0L);
            curl_easy_setopt(pCurl, CURLOPT_HEADER, 0L);
            fseek(pFile, uploadedLen, SEEK_SET);
            curl_easy_setopt(pCurl, CURLOPT_APPEND, 1L);
        }
        else
        {
            curl_easy_setopt(pCurl, CURLOPT_APPEND, 0L);
        }
        res = curl_easy_perform(pCurl);
    }
    fclose(pFile);

    qDebug() << "UploadFtp res:" << res;

    return res;
}

3.源代码程序下载(包含库封装和库调用两个工程):

下载地址:https://download.csdn.net/download/linyibin_123/87341139

六、测试结果

tftp测试结果:
在这里插入图片描述

ftp测试结果:
在这里插入图片描述

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
Qt是一个跨平台的C++应用程序开发框架,可以用于开发各种类型的应用程序,包括服务器应用程序TFTP(Trivial File Transfer Protocol)是一种简化的文件传输协议,在Qt中可以通过实现相关的网络类来实现TFTP服务器。 首先,我们需要创建一个Qt的服务器应用程序。可以使用Qt网络模块,包括QTcpServer和QTcpSocket类来实现QTcpServer用于监听和接受客户端的连接请求,QTcpSocket用于处理与客户端的通信。 在TFTP中,服务器应该提供一些基本的操作,例如读取文件(RRQ)和写入文件(WRQ)。为了实现这些操作,我们可以在服务器应用程序中使用QTcpSocket的readyRead信号来读取客户端发送的请求,并根据请求类型进行相应的处理。 例如,当收到RRQ请求时,服务器应该打开相应的文件并读取内容,然后通过QTcpSocket的write方法将文件内容发送给客户端。当收到WRQ请求时,服务器应该创建相应的文件,并通过QTcpSocket的read方法接收客户端发送过来的文件内容,然后写入到文件中。 此外,TFTP还包含一些其他的操作,例如错误报告(ERROR),服务器可选参数(OACK)等。我们可以通过在服务器应用程序实现相应的逻辑来处理这些操作。 总结起来,要在Qt实现TFTP服务器,我们需要使用Qt网络模块创建一个服务器应用程序,通过接收和处理客户端的请求,实现TFTP的基本操作。同时,还需要考虑处理错误报告和其他可选参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅笑一斤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值