zoukankan      html  css  js  c++  java
  • libcrul库

    对Qt的QFtp类太失望了, O_O...所以...

    官网: http://curl.haxx.se/

    libcurl-7.19.3-win32-ssl-msvc.zip

    选择windows系统的, 下载MSVC 带ssl的

    在虚拟机上用FileZilla搭建一个FTP服务器并创建可匿名空密码登录; 在Qt工程中包含必须的头文件, 引用必须的lib文件; 测试可以正常下载到文件

    支持ftp文件上传下载, 断点续传, 文件传输进度; 有待测试验证

    听说很强大而且性能不错, 真喜欢

    CurlTestProject

    要实现的功能:

    1.断点续传

    2.进度回馈 (下载百分比, 文件大小, 已下载大小, 下载速度...)

    3.暂停(断开数据传输连接, 不删除本地缓存数据)

    4.取消(断开数据传输连接, 并删除本地缓存数据)

    5.超时(连接超时-重连; 超时未收到数据流-重连; 整个下载任务过程超时-记录并取消下载)

    6.重连(断开实连接或虚连接)

    7.实连接(连接时通的, 可以正常收发数据包)

    8.虚连接(连接已经断开但程序没检测到, 以为链路是通的)

    9.限速(防止cup爆满; 防止网络流量大量占用 -服务端ftp工具可配置最大传输速度, 客户端程序也可提供相应配置接口)

    10.要可以浏览远程ftp服务器上的目录文件

    遇到的问题:

    1.路径的编码和文件名的编码不一样?

    现象:
    A情况
    ftp路径若包含中文字符, 文件名是英文字符
    Qt代码:
    curl_easy_setopt(this->curl, CURLOPT_URL, url.toLocal8Bit().data());
    可行
    
    B情况
    ftp路径若包含中文字符, 文件名也包含中文字符
    同样的代码执行会失败
    FileZilla服务端的监控工具看到文件名变成乱码
    但Qt代码为:
    curl_easy_setopt(this->curl, CURLOPT_URL, url.toStdString().c_str());
    是可行的, 但这样对于A情况就不行
    
    解决思路1:(验证过了, 行不通)
    把路径和文件名分开, 路径用toLocal8Bit转换编码, 文件名用toStdString转换

    解决思路2:(已验证, ok)
    百度一下, 听说FileZilla编码用的是utf8, 所以只要把url路径转成utf8格式就ok了
    curl_easy_setopt(this->curl,CURLOPT_URL,url.toUtf8().data()); //A B情况都行
    缺陷, 下载其他ftp服务器(非FileZilla)的文件又有编码问题
    据说可以给FileZilla服务端打编码问题的补
    解决思路3:(发神经了, 这样就行了嘛...)
    curl_easy_setopt(this->curl,CURLOPT_URL,url.toLocal8Bit().data());

     2.不知道怎么实现浏览远程ftp服务器目录文件

    经过困难的百度, 了解到可以直接发送FTP命令LIST(或NLST)来实现
    一开始不知道发送命令后, 如何获取结果; 后来猜测是跟文件下载的回调函数是同一个回调, 结果我猜对了..
    
    测试:
    curl_easy_setopt(easy_handle, CURLOPT_CUSTOMREQUEST, "NLST");
    可以返回文件名列表 --可以很简单的处理
    
    curl_easy_setopt(easy_handle, CURLOPT_CUSTOMREQUEST, "LIST");
    可以返回目录文件信息列表 --返回的格式稍微复杂一些....懒得去研究, 所以直接看Qt源码, 看它怎么处理LIST命令返回的结果, 然后直接考出它里面的代码来用, 直接ok了

     3.发布的时候提示没找到libsasl.dll动态库?

    下载的libcurl库压缩包里面根本没提供libsasl.dll这个动态库
    我奇怪为啥在我的机器上能跑; 到其他机器上就提示未找到这个文件
    后来全盘扫描本地文件, 发现svn安装目录下有这个动态库文件, 而svn目录已添加到环境变量里面; 所以本机可以运行
    
    解决方案: 把这个dll拷过去

     4.线程发射信号问题

    主线程创建一个从QThread类继承下来的工作线程, 有一个QObject继承下来的类对象成员, 该成员可以发出一个信号, 信号的参数是一个普通的类对象

    这样没错, 可以关联成员发出信号后, 被主线程接收

    class Param {
        ....
    };
    
    class Obj : QObject {
        ....
    signals:
        void sXXX(Param);
    };
    
    class Thread : public QThread {
    public:
        ....
    private:
        Obj obj;
    };
    //主线程可以间接关联到Obj对象发出的信号

    如果是这样的话就不行了:

    class Param {
        ....
    };
    
    class Obj : QObject {
        ....
    signals:
        void sXXX(Param);
    };
    
    class ThreadA : public QThread {
    public:
        ...
    private:
        Obj obj;
    };
    
    class ThreadB : public QThread {
    public:
        ....
    private:
        ThreadA* threadA;
    };

    //主线程创建ThreadA线程, ThreadA线程创建ThreadB线程, ThreadB线程类对象的obj成员发出的信号, 不能间接的关联到主线程中去

    好像关联上去; 该如何如何...

    解决方案:

    把线程对象由局部对象提升到成员变量

  • 相关阅读:
    【知识强化】第四章 网络层 4.1 网络层的功能
    【知识强化】第三章 数据链路层 3.8 数据链路层设备
    【知识强化】第三章 数据链路层 3.7 广域网
    【知识强化】第三章 数据链路层 3.6 局域网
    【知识强化】第三章 数据链路层 3.5 介质访问控制
    【知识强化】第三章 数据链路层 3.4 流量控制与可靠传输机制
    ASP.NET MVC入门之再不学习就真的out了
    ASP.NET MVC系列:添加模型的验证规则
    ASP.NET MVC系列:为已有模型添加新的属性
    ASP.NET MVC系列:为视图添加查询功能
  • 原文地址:https://www.cnblogs.com/jianc/p/2918718.html
Copyright © 2011-2022 走看看