本文主要讲解关于网盘文件操作部分的分享文件的逻辑设计部分,主要步骤如下:
目录
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、查看文件是否真正创建
测试成功