网盘—下载文件

本文主要讲解网盘文件操作的下载文件部分,具体步骤如下:

目录

1、实施步骤

2、代码实现

2.1、添加下载文件的协议

2.2、添加下载文件函数

2.3、添加信号槽

2.4、实现槽函数

2.5、设置download状态

2.6、添加定义

2.7、服务器接收数据

2.8、添加下载文件的case

2.9、测试------看一下客户端是否可以得到文件名和大小

A、点击下载文件,保存在桌面

B、终端输出,文件名字和大小

2.10、提取文件名和大小

2.11、收数据

2.12、服务器怎么发数据

2.12、发送文件给客户端

2.13、定义定时器,关联信号槽

2.14、发送文件给客户端

3、测试

3.1、点击需要下载的文件

[3.2、选择保存路径已经名称 叫做testt.h](#3.2、选择保存路径已经名称 叫做testt.h)

3.3、在桌面查看是否成功下载


1、实施步骤

A、客户端发送下载请求(请求包含路径,下载文件名)

B、服务器提取指定内容以及文件大小发送给客户端

C、客户端循环接收服务器发送过来的文件内容,保存到文件中(客户端需要指定一个位置来保存我们接收到的文件内容,QFileDialog)

2、代码实现

2.1、添加下载文件的协议

复制代码
    ENUM_MSG_TYPE_DOWNLOAD_FILE_REQUEST,  //下载文件请求
    ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND,  //下载文件回复

2.2、添加下载文件函数

复制代码
    //下载文件
    void downloadFile();

2.3、添加信号槽

复制代码
    //关联下载文件槽函数
    connect(m_pDownLoadPB, SIGNAL(clicked(bool)),
            this, SLOT(downloadFile()));

2.4、实现槽函数

复制代码
void Book::downloadFile()
{
    //获得下载的文件名字
    //获得当前所在的目录
    QString strCurPath = TcpClient::getinstance().curPath();
    //获得点击删除的文件
    QListWidgetItem *pItem =  m_pBookListW->currentItem();
    //判断
    if(NULL==pItem)
    {
        QMessageBox::warning(this,"下载文件","请选择要下载的文件");
    }
    else
    {
        //可能还没有输入路径的时候就已经回复了,所以放在前面        
        //定义存放位置
        QString strSaveFilePath = QFileDialog::getSaveFileName();
        if(strSaveFilePath.isEmpty())
        {
            QMessageBox::warning(this, "下载文件","请指定要保存的位置");
            strSaveFilePath.clear();
        }
        else {
            m_strSaveFilePath = strSaveFilePath;
        }
        
        
        
        //当前网盘所在的路径
        QString strCurPath = TcpClient::getinstance().curPath();
        PDU *pdu =mkPDU(strCurPath.size()+1);
        pdu->uiMsgType=ENUM_MSG_TYPE_DOWNLOAD_FILE_REQUEST;
        //文件名字
        QString strFileName = pItem->text();
        strncpy((char*)(pdu->caData),strFileName.toStdString().c_str(),strFileName.size());
        memcpy(pdu->caMsg,strCurPath.toStdString().c_str(),strCurPath.size());
        
        //发送给服务器
        TcpClient::getinstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);
        //可能还没有输入路径的时候就已经回复了
    }
}

2.5、设置download状态

复制代码
    //设置download的状态
    void setDownloadStatus(bool status);

2.6、添加定义

复制代码
void Book::setDownloadStatus(bool status)
{
    m_bDownload =status;
}

2.7、服务器接收数据

2.8、添加下载文件的case

复制代码
           //-----------下载文件--------------------------
        case ENUM_MSG_TYPE_DOWNLOAD_FILE_REQUEST:
        {
            //先把路径名字得到
            char caFileName[32] = {'\0'};
            strcpy(caFileName,pdu->caData);
            //产生一块空间,将传过来的路径拷贝出来
            char *pPath = new char[pdu->uiMsgLen];
            memcpy(pPath,pdu->caMsg,pdu->uiMsgLen);
            QString strPath = QString("%1/%2").arg(pPath).arg(caFileName);
            qDebug()<<strPath;
            //释放空间
            delete [] pPath;
            pPath = NULL;
            
            //服务器给回复
            //先发送一个大小
            QFileInfo fileinfo(strPath);
            qint64 filesize = fileinfo.size();
            PDU *respdu =mkPDU(0);
            respdu->uiMsgType = ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND;
            sprintf(respdu->caData,"%s %lld",caFileName,filesize);
            //发送给客户端
            write((char*)respdu,respdu->uiPDULen);
            free(respdu);
            respdu = NULL;  
            break;
        }

2.9、测试------看一下客户端是否可以得到文件名和大小

复制代码
        //---------------------下载文件文件------------------------
    case ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND:
    {
        qDebug()<<pdu->caData;
        //QMessageBox::information(this,"下载文件",pdu->caData);
        break;
    }

A、点击下载文件,保存在桌面

B、终端输出,文件名字和大小

2.10、提取文件名和大小

复制代码
        case ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND:
        {
            qDebug()<<pdu->caData;
            //QMessageBox::information(this,"下载文件",pdu->caData);
            //定义文件的名字
            char caFileName[32] ={'\0'};
            sscanf(pdu->caData, "%s %lld", caFileName, &(OpeWidget::getInstance().getBook()->m_iTotal));
            if(strlen(caFileName)>0 &&OpeWidget::getInstance().getBook()->m_iTotal >0)
            {
                OpeWidget::getInstance().getBook()->setDownloadStatus(true);//现在处于下载状态
                //打开文件
                m_file.setFileName(OpeWidget::getInstance().getBook()->getSaveFilePath());
                if(!m_file.open(QIODevice::WriteOnly))
                {
                    QMessageBox::warning(this, "下载文件","获得保存文件的路径失败");   
                }
            }
            break;
        }

2.11、收数据

复制代码
 else {//处于收数据的状态
        QByteArray buffer = m_tcpSocket.readAll();
        m_file.write(buffer);
        Book *pBook = OpeWidget::getInstance().getBook();
        pBook->m_Recived+=buffer.size();
        if(pBook->m_iTotal ==pBook->m_Recived)
        {
            m_file.close();
            pBook->m_iTotal =0;
            pBook->m_Recived =0;
            pBook->setDownloadStatus(false);
        }
        else if(pBook->m_iTotal ==pBook->m_Recived) {//收到的数据比原本的数据还要大
            m_file.close();
            pBook->m_iTotal =0;
            pBook->m_Recived =0;
            pBook->setDownloadStatus(false);
            QMessageBox::critical(this, "下载文件","下载文件失败");
        }
    }

2.12、服务器怎么发数据

2.12、发送文件给客户端

复制代码
//发送文件数据给客户端
    void sendFileToClient();

2.13、定义定时器,关联信号槽

复制代码
    m_pTimer = new QTimer;    
    connect(m_pTimer, SIGNAL(timeout()), this, SLOT(sendFileToClient()));

2.14、发送文件给客户端

复制代码
void MyTcpSocket::sendFileToClient()
{
    char *pData =new char[4096];
    qint64 ret =0;
    while (true) {
        ret = m_file.read(pData, 4096);
        if(ret>0 &&ret <=4096)
        {
            write(pData,ret);
        }
        else if (0==ret) {//所有文件都读取出来,并且发送完了
            m_file.close();
            break;
        }
        else if (ret<0) {
            qDebug()<<"发送文件内容给客户端过程中失败";
            m_file.close();
            break;
        }
    }
    delete [] pData;
    pData = NULL;
}

3、测试

3.1、点击需要下载的文件

3.2、选择保存路径已经名称 叫做testt.h

3.3、在桌面查看是否成功下载

发现桌面有哦

成功!!!!!!!!

相关推荐
物联网老王33 分钟前
Ubuntu Linux Cursor 安装与使用一
linux·运维·ubuntu
艾伦_耶格宇2 小时前
【ACP】阿里云云计算高级运维工程师--ACP
运维·阿里云·云计算
一位摩羯座DBA3 小时前
Redhat&Centos挂载镜像
linux·运维·centos
计算机毕设定制辅导-无忧学长3 小时前
西门子 PLC 与 Modbus 集成:S7-1500 RTU/TCP 配置指南(一)
服务器·数据库·tcp/ip
cui_win4 小时前
【网络】Linux 内核优化实战 - net.core.flow_limit_table_len
linux·运维·网络
风清再凯4 小时前
自动化工具ansible,以及playbook剧本
运维·自动化·ansible
深圳安锐科技有限公司4 小时前
深圳安锐科技发布国内首款4G 索力仪!让斜拉桥索力自动化监测更精准高效
运维·安全·自动化·自动化监测·人工监测·桥梁监测·索力监测
猫头虎4 小时前
猫头虎 AI工具分享:一个网页抓取、结构化数据提取、网页爬取、浏览器自动化操作工具:Hyperbrowser MCP
运维·人工智能·gpt·开源·自动化·文心一言·ai编程
cocologin6 小时前
RIP 技术深度解析
运维·网络·网络协议
cv高级工程师YKY6 小时前
SRE - - PV、UV、VV、IP详解及区别
大数据·服务器·uv