网盘——分享文件——逻辑设计

本文主要讲解关于网盘文件操作部分的分享文件的逻辑设计部分,主要步骤如下:

目录

1、实施步骤:

2、代码实现

2.1、添加分享文件协议

2.2、添加取消槽函数

2.3、关联取消选择的槽函数

2.4、添加取消槽函数的定义

2.5、添加全选函数槽函数

2.6、关联全选槽函数

2.7、添加全部选择槽函数的定义

2.8、确定取消分享按钮

2.9、关联槽函数

2.10、在共享文件函数部分获得文件名

2.11、添加确定分享文件的定义

2.12、服务器端添加接收分享文件case

2.13、在客户端添加通知信息的处理

2.14、服务器添加通知回复的case

2.15、取消分享文件,先把它隐藏起来

2.16、文件夹的分享

2.17、添加定义

2.18、在case中调用

2.19、测试文件夹的分享

A、用户登录,刷新好友

B、点击图书,刷新文件,共享文件,选择Lucy好友,确定

C、点击yes

D、刷新lucy文件

E、查看文件是否真正创建


1、实施步骤:

A、客户端发送分享文件请求(请求包含分享者、接收者、当前路径以及文件名)

那么PDU应该如何设置呢?分享者放在cadata里面,接收者放在camsg里面,当前路径也是camsg,那都放在一起了,如何做区分呢?将分享者和接收者的个数放在cadata里面,文件名也放在camsg或者将当前路径和文件名拼接,一起放在msg里面。

B、服务器端接收请求,对请求进行操作,并将操作结果返回给客户端

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

2、代码实现

2.1、添加分享文件协议

    ENUM_MSG_TYPE_SHARE_FILE_REQUEST,  //分享文件请求ENUM_MSG_TYPE_SHARE_FILE_RESPOND,  //分享文件回复

2.2、添加取消槽函数

    //添加分享文件槽函数void cancleSelect();//取消选择

2.3、关联取消选择的槽函数

    //关联取消选择信号槽connect(m_pCancelSelectPB,SIGNAL(clicked(bool)),this, SLOT(cancleSelect()));

2.4、添加取消槽函数的定义

void ShareFile::cancleSelect()
{//获得选择的checkboxQList<QAbstractButton*> cbList = m_pButtonGroup->buttons();//循环遍历listfor(int i=0; i<cbList.size(); i++){if(cbList[i]->isChecked()){cbList[i]->setChecked(false);}}
}

测试

点击取消选择

2.5、添加全选函数槽函数

    void allSelect();//全部选择

2.6、关联全选槽函数

    //关联全部选择信号槽connect(m_pSelectAllPB,SIGNAL(clicked(bool)),this, SLOT(allSelect()));

2.7、添加全部选择槽函数的定义

//分享文件全选
void ShareFile::allSelect()
{//获得选择的checkboxQList<QAbstractButton*> cbList = m_pButtonGroup->buttons();//循环遍历listfor(int i=0; i<cbList.size(); i++){if(!cbList[i]->isChecked()){cbList[i]->setChecked(true);}}
}

测试

2.8、确定取消分享按钮

    void okShare(); //确定分享void cancleShare();//取消分享

2.9、关联槽函数

    //关联确定分享信号槽connect(m_pOKPB,SIGNAL(clicked(bool)),this, SLOT(okShare()));//关联取消分享信号槽connect(m_pCancelPB,SIGNAL(clicked(bool)),this, SLOT(cancleShare()));

2.10、在共享文件函数部分获得文件名

void Book::shareFile()
{//获得点击删除的文件QListWidgetItem *pItem =  m_pBookListW->currentItem();//判断if(NULL==pItem){QMessageBox::warning(this,"分享文件","请选择分享的文件");return;}else{//获得分享的文件名//文件名字m_strShareFileName = pItem->text();        }//获得好友列表Friend *pFriend = OpeWidget::getInstance().getFriend();QListWidget *pFriendList = pFriend->getFriendlist();ShareFile::getinstance().updateFriend(pFriendList);if(ShareFile::getinstance().isHidden()){ShareFile::getinstance().show();}
}

2.11、添加确定分享文件的定义

//确定分享文件
void ShareFile::okShare()
{//谁分享的QString strName =  TcpClient::getinstance().loginName();//当前的路径QString strCurPath = TcpClient::getinstance().curPath();//获得共享的文件名QString strShareFileName = OpeWidget::getInstance().getBook()->getShowFileName();QString strPath = strCurPath +"/"+strShareFileName;//获得接收者//获得选择的checkboxQList<QAbstractButton*> cbList = m_pButtonGroup->buttons();int num =0;//循环遍历listfor(int i=0; i<cbList.size(); i++){if(cbList[i]->isChecked()){num++;}}PDU *pdu = mkPDU(32*num+strPath.size()+1);pdu->uiMsgType = ENUM_MSG_TYPE_SHARE_FILE_REQUEST;sprintf(pdu->caData, "%s %d", strName.toStdString().c_str(),num);int j =0;for(int i=0;i<cbList.size();i++){if(cbList[i]->isChecked()){memcpy((char*)(pdu->caMsg)+j*32, cbList[i]->text().toStdString().c_str(), cbList[i]->text().size());j++;}}//将路径拷贝进去memcpy((char*)(pdu->caMsg)+num*32, strPath.toStdString().c_str(), strPath.size());TcpClient::getinstance().getTcpSocket().write((char*)pdu, pdu->uiPDULen);free(pdu);pdu=NULL;
}

2.12、服务器端添加接收分享文件case

  case ENUM_MSG_TYPE_SHARE_FILE_REQUEST:{char caSendName[32] = {'\0'};int num = 0;sscanf(pdu->caData, "%s%d", caSendName, &num);int size = num*32;PDU  *respdu = mkPDU(pdu->uiMsgLen-size);respdu->uiMsgType =ENUM_MSG_TYPE_SHARE_FILE_NOTE;strcpy(respdu->caData,caSendName);memcpy(respdu->caMsg, (char*)(pdu->caMsg)+size, pdu->uiMsgLen-size);//通知给谁char caReceName[32] = {'\0'};for(int i=0;i<num;i++){memcpy(caReceName, (char*)(pdu->caMsg)+i*32, 32);MyTcpServer::getInstance().reSend(caReceName, respdu);}free(respdu);respdu=NULL;respdu=mkPDU(0);respdu->uiMsgType = ENUM_MSG_TYPE_SHARE_FILE_RESPOND;strcpy(respdu->caData, SHARE_FILE_OK);write((char*)respdu, respdu->uiPDULen);free(respdu);respdu=NULL;break;}

2.13、在客户端添加通知信息的处理

            //---------------------分享文件------------------------case ENUM_MSG_TYPE_SHARE_FILE_RESPOND:{QMessageBox::information(this,"共享文件",pdu->caData);break;}case ENUM_MSG_TYPE_SHARE_FILE_NOTE:{//是否接收对方共享的文件char *pPath = new char[pdu->uiMsgLen];memcpy(pPath, pdu->caMsg,pdu->uiMsgLen);// //aa//bb/ccchar *pos =  strrchr(pPath, '/');qDebug()<<pos;if(NULL != pos){//表示找到了pos++;QString strNote = QString("%1 share file->%2 \n Do you accept?").arg(pdu->caData).arg(pos);int ret = QMessageBox::information(this,"共享文件",strNote);if(QMessageBox::Yes==ret){PDU *respdu = mkPDU(pdu->uiMsgLen);respdu->uiMsgType =ENUM_MSG_TYPE_SHARE_FILE_NOTE_RESPOND;memcpy(respdu->caMsg, pdu->caMsg,pdu->uiMsgLen);//接收者名字QString strName = TcpClient::getinstance().loginName();strcpy(respdu->caData,strName.toStdString().c_str());m_tcpSocket.write((char*)respdu, respdu->uiPDULen);}}break;}

2.14、服务器添加通知回复的case

        case ENUM_MSG_TYPE_SHARE_FILE_NOTE_RESPOND:{QString strRecvPath = QString("./%1").arg(pdu->caData);//共享者文件路径QString strShareFilePath = QString("%1").arg((char*)(pdu->caMsg));//拼接名字int index = strShareFilePath.lastIndexOf('/');QString strFileName = strShareFilePath.right(strShareFilePath.size()-index-1);strRecvPath =strRecvPath +'/' +strFileName;//拷贝文件QFileInfo fileinfo(strShareFilePath);if(fileinfo.isFile()){QFile::copy(strShareFilePath,strRecvPath);}else  if(fileinfo.isDir()){}break;}

测试 登录jack和lucy这两个好友,刷新jack的文件,将test.txt文件发送给lucy,弹出窗口提示之后,刷新lucy文件,发现分享文件成功

成功

2.15、取消分享文件,先把它隐藏起来

//取消分享文件
void ShareFile::cancleShare()
{hide();
}

2.16、文件夹的分享

 //分享文件——文件夹的拷贝void copyDir(QString strSrcDir, QString strDestDir);

2.17、添加定义

void MyTcpSocket::copyDir(QString strSrcDir, QString strDestDir)
{//创建目标文件QDir dir;dir.mkdir(strDestDir);//产生一个目录//打开原来要拷贝的目录dir.setPath(strSrcDir);QFileInfoList fileInfoList =  dir.entryInfoList();QString srcTmp;QString destTmp;//遍历listfor(int i=0;i<fileInfoList.size();i++){if(fileInfoList[i].isFile()){//如果是常规文件            qDebug()<<"filename:"<<fileInfoList[i].fileName();srcTmp = strSrcDir + '/' +fileInfoList[i].fileName();destTmp = strDestDir + '/' +fileInfoList[i].fileName();QFile::copy(srcTmp,destTmp);}else if (fileInfoList[i].isDir()) {if(QString(".") == fileInfoList[i].fileName()||QString("..") == fileInfoList[i].fileName()){continue;}srcTmp = strSrcDir + '/' +fileInfoList[i].fileName();destTmp = strDestDir + '/' +fileInfoList[i].fileName();copyDir(srcTmp,destTmp);//如果是子文件夹,递归进行拷贝}}
}

2.18、在case中调用

 case ENUM_MSG_TYPE_SHARE_FILE_NOTE_RESPOND:{QString strRecvPath = QString("./%1").arg(pdu->caData);//共享者文件路径QString strShareFilePath = QString("%1").arg((char*)(pdu->caMsg));//拼接名字int index = strShareFilePath.lastIndexOf('/');QString strFileName = strShareFilePath.right(strShareFilePath.size()-index-1);strRecvPath =strRecvPath +'/' +strFileName;//拷贝文件QFileInfo fileinfo(strShareFilePath);if(fileinfo.isFile()){QFile::copy(strShareFilePath,strRecvPath);}else if(fileinfo.isDir()){copyDir(strShareFilePath,strRecvPath);}break;}

2.19、测试文件夹的分享

A、用户登录,刷新好友

B、点击图书,刷新文件,共享文件,选择Lucy好友,确定

C、点击yes

D、刷新lucy文件

E、查看文件是否真正创建

测试成功 

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

CTF-WEB(MISC)

安全攻防知识——CTF之MISC - 知乎 CTF之MISC杂项从入门到放弃_ctf杂项 你的名字-CSDN博客 CTF MICS笔记总结_archpr 掩码攻击-CSDN博客 一、图片隐写 CTF杂项---文件类型识别、分离、合并、隐写_ctf图片分离-CSDN博客 EXIF&#xff08;Exchangeable Image File&#xff09;是…

【Qt QML】QLibrary加载共享库中的类

QLibrary是一个用于加载动态链接库&#xff08;或称为共享库&#xff09;的类。它提供了一种独立于平台的方式来访问库中的功能。 在QLibrary中&#xff0c;可以通过构造函数或setFileName()方法设置要加载的库文件名。当加载库文件时&#xff0c;QLibrary会搜索所有平台特定的…

设计模式: 责任链模式

目录 一&#xff0c;责任链模式 二&#xff0c;特点 四&#xff0c;实现步骤 五&#xff0c;代码 一&#xff0c;责任链模式 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种软件设计模式&#xff0c;它属于行为型模式。在这种模式中&#xff0c…

量子城域网建设设备系列(二):量子密钥管系统(KMS)

在上文介绍光量子交换机的文章中我们提到&#xff0c;量子保密通信网络的通道切换是由量子密钥管理系统&#xff08;Key Management System&#xff0c;KMS&#xff09;给光量子交换机下发信道切换指令&#xff0c;实现整个网络中任意两对量子密钥分发终端的量子信道互联互通&a…

数据分析--客户价值分析RFM(分箱法/标准化)

原数据 原数据如果有异常或者缺失等情况&#xff0c;要先对数据进行处理 &#xff0c;再进行下面的操作&#xff0c;要不然会影响结果的正确性 一、根据RFM计算客户价值并对客户进行细分 1. 数据预处理 1.1 创建视图存储 R、F、M的最大最小值 创建视图存储R 、F、M 的最大最小…

探索高级聚类技术:使用LLM进行客户细分

在数据科学领域&#xff0c;客户细分是理解和分析客户群体的重要步骤。最近&#xff0c;我发现了一个名为“Clustering with LLM”的GitHub仓库&#xff0c;它由Damian Gil Gonzalez创建&#xff0c;专门针对这一领域提供了一些先进的聚类技术。在这篇文章中&#xff0c;我将概…

Java中使用Redis实现分布式锁的三种方式

1. 导语 随着软件开发领域的不断演进,并发性已经成为一个至关重要的方面,特别是在资源跨多个进程共享的分布式系统中。 在Java中,管理并发性对于确保数据一致性和防止竞态条件至关重要。 Redis作为一个强大的内存数据存储,为在Java应用程序中实现分布式锁提供了一种高效的…

VTK 的可视化方法:Cutting Probing

VTK 的可视化方法&#xff1a;Cutting & Probing VTK 的可视化方法&#xff1a;Cutting & ProbingCuttingProbing VTK 的可视化方法&#xff1a;Cutting & Probing Cutting 和 Probing 都是对三维数据截取二维平面的方法。它们的区别是&#xff1a; Cutting 使用…

Java-异常处理-处理RuntimeException(2/2)

下面有一个简单的整数除法运算程序&#xff0c;输入两个整数作为被除数和除数&#xff0c;在正常情况下&#xff0c;会输出两数相除的整数商。 import java.util.Scanner; public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.i…

私域运营的崛起:企业第三极销售渠道的战略思考与定制开发AI智能名片B2B2C商城小程序

在数字化营销的新时代&#xff0c;私域运营如同璀璨新星&#xff0c;已然崛起为企业不可或缺的第三极销售渠道。那么&#xff0c;如何善用这一新兴领域的价值&#xff0c;使之为企业带来持续增长和竞争力&#xff0c;已成为众多企业需要从战略层面深入思考的问题。而在这一过程…

Node.js -- MongoDB

文章目录 1. 相关介绍2. 核心概念3. 命令行交互3.1数据库命令3.2 集合命令3.3 文档命令 4. 数据库应用场景4.1 新增4.2 删除4.3 更新4.4 查询 5. 图形化工具Robo 3T 1. 相关介绍 一、简介 Mongodb是什么 MongoDB是一个基于分布式文件存储的数据库&#xff0c;官方地址https://…

如何使用免费软件从Mac恢复音频文件?

要从Mac中删除任何文件&#xff0c;背后是有原因的。大多数Mac用户都希望增加Mac中的空间&#xff0c;这就是为什么他们更喜欢从驱动器中删除文件以便出现一些空间的原因。一些Mac用户错误地删除了该文件&#xff0c;无法识别这是一个重要文件。例如&#xff0c;他们错误地从Ma…

C++_set和map的学习

1. 关联式容器 STL中的容器有序列式容器和关联式容器。 其中 vector 、 list 、 deque 、 forward_list(C11)就是序列式容器&#xff0c; 因为其底层为线性序列的数据结构&#xff0c;里面 存储的是元素本身 关联式容器 也是用来存储数据的&#xff0c;与序列式容器不同的是&am…

Leetcode 108.将有序数组转换为二叉搜索树

题目描述 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#xff1a;[0,-10,5,null,-3,null,9] 也将被…

牛客网刷题 | BC73 计算一元二次方程

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 从键盘输入a, b, c的…

Scala应用 —— JDBC的创建

文章目录 Scala应用 —— JDBC的创建前言一、JDBC的创建过程1.初始化连接1.1 配置驱动1.2 创建连接对象 2. 初始化执行器2.1 创建执行器对象2.2 初始化执行器参数 3. 执行操作并返回结果 二、Scala JDBC的基本设计思路1. 操作步骤设计2. 解决结果差异化3.实现jdbc方法并输出结果…

使用unreal engine5.3.2创建c++第一人称游戏

UE5系列文章目录 文章目录 UE5系列文章目录前言一、NuGet 简介二、解决方法&#xff1a; 前言 为了使用unreal engine5.3.2创建c第一人称游戏&#xff0c;今天安装了Visual Studio 2022专业版。在ue5中创建c工程&#xff0c;结果编译器报错&#xff1a; 严重性 代码 说明 项目…

ThreeJS:坐标辅助器与轨道控制器

ThreeJS与右手坐标系 使用ThreeJS创建3D场景时&#xff0c;需要使用一个坐标系来定位和控制对象的位置和方向。 ThreeJS使用的坐标系是右手坐标系&#xff0c;即&#xff1a;X轴向右、Y轴向上、Z轴向前&#xff0c;如下图所示&#xff0c; ThreeJS-右手坐标系 Tips&#xff1a;…

python 11Pandas数据可视化实验

实验目的&#xff1a; 学会使用Pandas操作数据集&#xff0c;并进行可视化。 数据集描述&#xff1a; 该数据集是CNKI中与“中药毒理反应”相关的文献信息&#xff0c;包含文章题目、作者、来源&#xff08;出版社&#xff09;、摘要、发表时间等信息。 实验要求&#xff1…

文件传送协议

壹、文件传输协议FTP 一、FTP简介 文件传送协议FTP曾是互联网上使用最广泛的协议&#xff1b; 在互联网发展的早期阶段&#xff0c;用FTP传送文件约占整个互联网的通信量的三分之一&#xff1b;知道1995年&#xff0c;www的通信量才首次超过FTP。 FTP实现的是通过网络实现异…