网盘—上传文件

本文主要讲解网盘里面关于文件操作部分的上传文件,具体步骤如下

目录

1、实施步骤:

2、代码实现

2.1、添加上传文件协议

2.2、添加上传文件槽函数

2.3、添加槽函数定义

2.4、关联上传槽函数

2.5、服务器端

2.6、在服务器端添加上传文件请求的case

2.7、客户端上传内容

2.8、添加定时器

2.9、关联信号槽

2.10、添加槽函数定义

2.11、打开服务器,接收上传文件内容

3、测试

A、点击上传文件,选择文件并打开

 B、提示上传成功

C、发现jack文件夹里面也有了makefile文件

D、大的文件也可以上传


1、实施步骤:

 A、客户端发送上传文件请求,请求包括:包括当前路径上传文件名上传文件内容

包括当前路径,上传文件名,这个时候不上传文件内容,当服务器接收到上传请求之后,在指定的路径下面,将该文件创建出来,客户端发送上传请求之后,上传文件内容。

B、服务器接收到客户端文件内容,将信息保存到之前创建的文件中,在服务器接受完上传的内容之后,服务器发送信息给客户端

C、客户端接受回复信息并显示

2、代码实现

2.1、添加上传文件协议

    ENUM_MSG_TYPE_UPLOAD_FILE_REQUEST,  //上传文件请求
    ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND,  //上传文件回复

2.2、添加上传文件槽函数

    //上传文件
    void uploadFile();

2.3、添加槽函数定义

void Book::uploadFile()
{
    //当前路径
    QString strCurPath = TcpClient::getinstance().curPath();
    //选择上传文件
    //QFileDialog::getOpenFileName();会弹出一个窗口来,类似于打开文件
    QString strUploadFilePath = QFileDialog::getOpenFileName();
    //qDebug()<<strUploadFilePath;
    //将名字提取出来
    if(!strUploadFilePath.isEmpty())
    {
        // aa/bb/cc 5 8
        int index = strUploadFilePath.lastIndexOf('/');
        QString strFileName =strUploadFilePath.right(strUploadFilePath.size()-index-1);
        //qDebug()<<strFileName;
        //将数据封装到PDU里面
        QFile file(strUploadFilePath);
        qint64 filesize = file.size();//获得文件大小
        PDU *pdu =mkPDU(strCurPath.size()+1);
        pdu->uiMsgType=ENUM_MSG_TYPE_UPLOAD_FILE_REQUEST;
        memcpy(pdu->caMsg, strCurPath.toStdString().c_str(),strCurPath.size());
        //"%s %lld" %s文件名 lld文件大小long long 64
        sprintf(pdu->caData,"%s %lld", strFileName.toStdString().c_str(),filesize);
        //发送
        //发送给服务器
        TcpClient::getinstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);
        free(pdu);
        pdu=NULL;
    }
    else {
        QMessageBox::warning(this, "上传文件","上传文件名字不能为空!");
    }

}

2.4、关联上传槽函数

    //关联上传文件信号槽
    connect(m_pUpLoadPB,SIGNAL(clicked(bool)),
            this, SLOT(uploadFile()));

2.5、服务器端

添加私有成员

 QFile m_file;
    //文件总的大小
    qint64 m_iTotal;
    qint64 m_iReceived;//每一次接受了多少文件
    bool m_bUpload; //现在处于上传文件状态还是其他状态

2.6、在服务器端添加上传文件请求的case

case ENUM_MSG_TYPE_UPLOAD_FILE_REQUEST:
        {
            char caFileName[32] = {'\0'};
            qint64  fileSize =0;
            //将文件名字提取出来
            sscanf(pdu->caData, "%s %lld", caFileName,&fileSize);
            //产生一块空间,将传过来的路径拷贝出来
            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;
            
            //根据拼接的路径将文件打开
            m_file.setFileName(strPath);
            //以只写的方式打开,如果这个文件不存在的话就会创建这个文件
            if(m_file.open(QIODevice::WriteOnly))
            {
                m_bUpload = true;
                m_iTotal =fileSize;
                m_iReceived = 0;
                
            }
            
            
            break;
        }

2.7、客户端上传内容

2.8、添加定时器

    //创建定时器
    void uploadFileData();    

2.9、关联信号槽

    //关联定时器信号槽
    connect(m_pTimer,SIGNAL(timeout()),
            this, SLOT(uploadFileData()));

2.10、添加槽函数定义

void Book::uploadFileData()
{
    m_pTimer->stop();//先关了,要不然他会重新计时
    QFile file(m_strUploadFilePath);
    if(!file.open(QIODevice::ReadOnly))
    {
        QMessageBox::warning(this,"上传文件", "打开文件失败");
        return;
    }
    
    char *pBuffer = new char[4096];
    qint64 ret =0;
    while (true) {
        ret = file.read(pBuffer,4096);
        if(ret>0&&ret<=4096)
        {
            //读到了数据
            TcpClient::getinstance().getTcpSocket().write(pBuffer,ret);
        }
        else if(0==ret){//数据已经读到了末尾了
            break;
        }
        else {
            QMessageBox::warning(this, "上传文件", "上传文件失败,读文件失败");
            break;
        }
    }
    file.close();
    delete [] (pBuffer);
    pBuffer=NULL;
}
void Book::uploadFile()
{
    //当前路径
    QString strCurPath = TcpClient::getinstance().curPath();
    //选择上传文件
    //QFileDialog::getOpenFileName();会弹出一个窗口来,类似于打开文件
    m_strUploadFilePath = QFileDialog::getOpenFileName();
    //qDebug()<<strUploadFilePath;
    //将名字提取出来
    if(!m_strUploadFilePath.isEmpty())
    {
        // aa/bb/cc 5 8
        int index = m_strUploadFilePath.lastIndexOf('/');
        QString strFileName =m_strUploadFilePath.right(m_strUploadFilePath.size()-index-1);
        //qDebug()<<strFileName;
        //将数据封装到PDU里面
        QFile file(m_strUploadFilePath);
        qint64 filesize = file.size();//获得文件大小
        PDU *pdu =mkPDU(strCurPath.size()+1);
        pdu->uiMsgType=ENUM_MSG_TYPE_UPLOAD_FILE_REQUEST;
        memcpy(pdu->caMsg, strCurPath.toStdString().c_str(),strCurPath.size());
        //"%s %lld" %s文件名 lld文件大小long long 64
        sprintf(pdu->caData,"%s %lld", strFileName.toStdString().c_str(),filesize);
        //发送
        //发送给服务器
        TcpClient::getinstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);
        free(pdu);
        pdu=NULL;
        
        //添加一个定时器防止数据粘连
        m_pTimer->start(1000);
        
    }
    else {
        QMessageBox::warning(this, "上传文件","上传文件名字不能为空!");
    }
}

2.11、打开服务器,接收上传文件内容

        //接收数据
        PDU *respdu = NULL;
        respdu =mkPDU(0);
        respdu->uiMsgType = ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND;
        QByteArray buff = readAll();//接收读到的数据
        m_file.write(buff);//将读到的数据写道buff里面去
        m_iReceived+=buff.size();
        if(m_iTotal==m_iReceived)
        {//接收数据结束了
            m_file.close();
            m_bUpload = false;
            strcpy(respdu->caData,UPLOAD_FILE_OK);
            //发送给客户端
            write((char*)respdu, respdu->uiPDULen);
            free(respdu);
            respdu =NULL;
        }
        else if ((m_iTotal<m_iReceived))
        {
            m_file.close();
            m_bUpload = false;
            strcpy(respdu->caData,UPLOAD_FILE_FAILED);
            //发送给客户端
            write((char*)respdu, respdu->uiPDULen);
            free(respdu);
            respdu =NULL;
        }
    }
}

2.12、客户端处理

        //---------------------上传文件------------------------
    case ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND:
    {        
        QMessageBox::information(this,"进入文件夹",pdu->caData);
        break;
    }  

3、测试

A、点击上传文件,选择文件并打开

 B、提示上传成功

C、发现jack文件夹里面也有了makefile文件

D、大的文件也可以上传

成功!!!!!!!!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/582162.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

4G远程温湿度传感器在农业中的应用—福建蜂窝物联网科技有限公司

解决方案 农业四情监测预警解决方案 农业四情指的是田间的虫情、作物的苗情、气候的灾情和土壤墒情。“四情”监测预警系统的组成包括管式土壤墒情监测站、虫情测报灯、气象站、农情监测摄像机&#xff0c;可实时监测基地状况,可以提高监测的效率和准确性&#xff0c;为农业生…

分布式系统事务一致性解决方案(基于事务消息)

参考&#xff1a;https://rocketmq.apache.org/zh/docs/featureBehavior/04transactionmessage/ 文章目录 概要错误的方案方案一&#xff1a;业务方自己实现方案二&#xff1a;RocketMQ 事务消息什么是事务消息事务消息处理流程事务消息生命周期使用限制使用示例使用建议 概要 …

进迭时空宣布开源RISC-V芯片的AI核心技术

仟江水商业电讯&#xff08;4月29日 北京 委托发布&#xff09;4月29日&#xff0c;在“创芯生生不息——进迭时空2024年度产品发布会”上&#xff0c;进迭时空CEO、创始人&#xff0c;陈志坚博士宣布将开源进迭时空在自研RISC-V AI CPU上的核心技术&#xff0c;包括AI扩展指令…

数据科学导论续

一、大数据采集的流程和方法 大数据采集的流程和方法 系统日志采集方法 很多互联网企业都有自己的海量数据采集工具&#xff0c;多用于系统日志采集&#xff0c;例如&#xff1a; Flume&#xff1a;分布式日志收集系统&#xff0c;最初由Cloudera开发&#xff0c;现是Apache的…

SPSS之判别分析

SPSS的判别分析过程中默认使用的是Fisher判别法和Bayes判别法&#xff0c;并以前者为主&#xff0c;在指定选项后也可以给出Bayes判别法的结果。 SPSS中判别分析在【分析】—【分类】—【判别】中完成。选定类别变量放入【分组变量】框中&#xff0c;单击定义范围(D)按钮给出类…

《Fundamentals of Power Electronics》——Buck、Boost、Buck-Boost三个电路的CCM-DCM工作特性总结

Buck、Boost、Buck-Boost这三个电路的CCM-DCM工作特性总结如下表所示&#xff1a; Buck、Boost、Buck-Boost这三个电路工作在DCM模式下电压传输比的对比图如下所示&#xff1a; 由上图可知&#xff0c;Buck-Boost电路的工作特性是一条斜率为的直线&#xff0c;Buck电路和Boost电…

IDEA 中的奇技淫巧

IDEA 中的奇技淫巧 书签 在使用ctrlalt方向键跳转时&#xff0c;或者追踪代码时&#xff0c;经常遇到的情况是层级太多&#xff0c;找不到代码的初始位置&#xff0c;入口。可以通过书签的形式去打上一个标记&#xff0c;后续可以直接跳转到书签位置。 标记书签&#xff1a;c…

Qt窗口

QMainWindow Qt 窗⼝ 是通过 QMainWindow类 来实现的。 QMainWindow 是⼀个为⽤⼾提供主窗⼝程序的类&#xff0c;继承⾃ QWidget 类&#xff0c;并且提供了⼀个预定义的 布局。QMainWindow 包含 ⼀个菜单栏&#xff08;menu bar&#xff09;、多个⼯具栏(tool bars)、多个浮动…

Python并发编程:揭开多线程与异步编程的神秘面纱

第一章&#xff1a;并发编程导论 1.1 并发与并行概念解析 1.1.1 并发性与并行性的区别 想象一下繁忙的厨房中多位厨师同时准备不同的菜肴——即使他们共享有限的空间和资源&#xff0c;也能协同工作&#xff0c;这就是并发性的一个生动比喻。并发性意味着多个任务在同一时间…

getchar和putchar的用法

getchar() 和 putchar() 是一对字符输入/输出函数.他们通常比scanf() 和printf() 函数更快更便捷。 getchar()不带任何参数&#xff0c;其实getchar() 和putchar()与scanf() 和printf()功能相似。 接下来博主简单的跟大家解释一下。 1.getchar 通常把输入的字符赋予一个字符变…

uReport2 报表设计

最近刚好用到这个报表工具&#xff0c;刚开始接触都还不会用&#xff0c;学习了一下&#xff0c;在这边做个记录。 数据源 目前报表框架支持和使用的数据源连接有两种方式&#xff1a;添加数据库连接 和添加内置数据源连接。 进入报表设计 http://IP:端口/context-path/urepor…

计算机网络之传输层TCP\UDP协议

UDP协议 用户数据报协议UDP概述 UDP只在IP数据报服务之上增加了很少功能&#xff0c;即复用分用和差错检测功能 UDP的主要特点&#xff1a; UDP是无连接的&#xff0c;减少开销和发送数据之前的时延 UDP使用最大努力交付&#xff0c;即不保证可靠交付&#xff0c;可靠性由U…

一款神奇的地理数据可视化python库

在地理信息系统&#xff08;GIS&#xff09;和地理数据可视化领域&#xff0c;Python的易用性和强大的库支持使其成为处理地理数据的理想选择之一。今天我们介绍Cartopy库&#xff0c;它为地理数据可视化提供了强大的支持。无论是对于GIS专业人士还是对地理数据可视化感兴趣的初…

网络编程——TCP

socket socket类型 流式套接字(SOCK_STREAM) TCP 提供了一个面向连接、可靠的数据传输服务&#xff0c;数据无差错、无重复、无丢失、无失序的发送且按发送顺序接收。内设置流量控制&#xff0c;避免数据流淹没慢的接收方。数据被看作是字节流&#xff0c;无长度限制。 数据报…

异常处理方式

在定义方法时&#xff0c;首先需要先对参数数据进行合法判断 数据若不合法&#xff0c;使用抛出异常的方式来告诉调用者&#xff0c;传递合法的数据进来 在方法内使用 throw 抛出指定异常对象&#xff0c;throw new XxxException(“异常产生原因”) 创建的是运行时异常&…

ROS学习笔记(14)拉普拉斯变换和PID

0.前提 近些时间在对睿抗的ROS仿真赛进行小组安排&#xff0c;对小组成员进行了一些安排&#xff0c;也要求他们以本次比赛写下自己的比赛经历博客&#xff0c;他们的培训由我来安排和负责&#xff0c;因此我得加吧油&#xff0c;起码保证我的进度得快过他们&#xff0c;才能安…

使用yolov8+QT+onnrunxtime进行开发的注意事项

1、本来想尝试做一个C的yolov8在QT5.15.2的应用&#xff1b; 因此&#xff0c;在实现这个目标的时候&#xff0c;我先用了yolov8自带的export进行导出&#xff0c;使用的代码很简单&#xff0c;如下所示&#xff1a; import os from ultralytics import YOLO# model YOLO(&q…

SpringBoot 快速开始 Dubbo RPC

文章目录 SpringBoot 快速开始 Dubbo RPC下载 Nacos项目启动项目的创建创建主项目接口定义服务的创建Dubbo 服务提供者的创建服务的消费者创建 添加依赖给 Provider、Consumer 添加依赖 开始写代码定义接口在 Provider 中实现在 Consumer 里面使用创建启动类 注册中心配置启动 …

绘唐科技AIGC怎么激活

绘唐科技AIGC怎么激活绘唐科技AIGC怎么激活绘唐科技AIGC怎么激活绘唐科技AIGC怎么激活 这里激活免费3天体验 Docshttps://qvfbz6lhqnd.feishu.cn/wiki/D3YLwmIzmivZ7BkDij6coVcbn7W

架构师技能:技术深度硬实力透过问题看本质--深入分析nginx偶尔502错误根因

以架构师的能力标准去分析每个问题&#xff0c;过后由表及里分析问题的本质&#xff0c;复盘总结经验&#xff0c;并把总结内容记录下来。当你解决各种各样的问题&#xff0c;也就积累了丰富的解决问题的经验&#xff0c;解决问题的能力也将自然得到极大的提升。励志做架构师的…