马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
Client 界面:
Server 界面:
Server 利用:
输入端口号后,点击启动监听
Client 利用:
1.毗连服务器
输入IP(服务器的IP所在)和端口号后,点击毗连按钮,毗连成功如下图所示:
2.向服务器发送文件
2.1 点击“选择当地文件”按钮,选择一个当地的文件。
2.2 点击“选择存储在服务器的目录”,选择发送的文件将要存储在服务器的哪个目录中。(此功能可直接在一台电脑上测试,当多台电脑的时候可以将目录改为服务器的现实目录所在)
2.3 点击“发送文件”按钮,即可开始向服务器传输文件,传输成功后客户端会有提示框。
3.下载服务器的文件(服务器向客户端发送文件)
3.1 点击“选择要下载的文件”按钮,选择想要下载的服务器下的文件(此功能可直接在一台电脑上测试,当多台电脑的时候可以将目录改为服务器的现实文件所在)。
3.2 点击“选择下载目录”按钮,选择下载文件的存储位置。
3.3 点击“下载文件”按钮,即可开始下载服务器的文件,下载成功后客户端会有提示框。
Server-Mainwindow焦点代码
- //设置进度条
- ui->progressBar->setRange(0,100);
- ui->progressBar->setValue(0);
- QWidget *progressWidget = new QWidget(this);
- progressWidget->setLayout(new QHBoxLayout());
- progressWidget->layout()->addWidget(ui->progressBar);
- // 创建 QStatusBar
- // 将小部件添加到 QStatusBar
- ui->statusbar->addPermanentWidget(progressWidget);
- // 设置主窗口的状态栏
- setStatusBar(ui->statusbar);
- ui->statusbar->setSizeGripEnabled(false);
- //创建线程对象
- QThread *thread = new QThread;
- //创建任务对象
- RecvFile *recvWork = new RecvFile;
- //将任务对象移到子线程中
- recvWork->moveToThread(thread);
- connect(this,&MainWindow::startListen,recvWork,&RecvFile::startListen);
- //更新进度条
- connect(recvWork,&RecvFile::curPercent,ui->progressBar,&QProgressBar::setValue);
- //启动线程
- thread->start();
复制代码 Server-receiver.cpp焦点代码
- void RecvFile::startListen(unsigned short port)
- {
- qDebug()<<port;
- //分配内存空间
- tcpServer = new QTcpServer(this);
- tcpServer->listen(QHostAddress::Any,port);
- connect(tcpServer,&QTcpServer::newConnection,[=]()
- {
- //取出建立好连接的套接字
- tcpSocket = tcpServer->nextPendingConnection();
- isStart = true;
- connect(tcpSocket,&QTcpSocket::readyRead,this,&RecvFile::recvFile);
- connect(tcpSocket,&QTcpSocket::disconnected,this,[=]()
- {
- //断开连接
- tcpSocket->close();
- tcpSocket->deleteLater();
- });
- });
- }
- void RecvFile:: recvFile()
- {
- qDebug()<<"触发recvFile";
- //取出接收的内容
- QByteArray buf = tcpSocket->readAll();
- if(true == isStart)//之前未接收文件的头部信息
- {
- //接收头部
- qDebug()<<"接收头部===";
- isStart = false;
- //解析头部 buf的内容格式 <文件名>##<文件大小>
- QString token=QString(buf).section("##",0,0);//token
- qDebug()<<"token1="<<token;
- recvfilesize = 0;//初始化已接收的文件长度为0
- if(token=="197%*FILE*%197"){//是文件
- qDebug()<<"文件";
- filename = QString(buf).section("##",1,1);//文件名
- filesize = QString(buf).section("##",2,2).toUInt();//文件大小
- targetDir=QString(buf).section("##",3,3);//文件应存储的目录
- qDebug()<<"filename="<<filename;
- qDebug()<<"filesize="<<filesize;
- qDebug()<<"targetDir="<<targetDir;
- }
- else if(token=="197%*DOWNLOAD*%197"){//请求下载文件信号
- qDebug()<<"下载文件请求";
- filePath = QString(buf).section("##",1,1);//文件完整路径
- storagePath = QString(buf).section("##",2,2);//文件完整路径
- qDebug()<<"filePath="<<filePath;
- qDebug()<<"storagePath="<<storagePath;
- isStart = true;//信号只是个头,不应该继续接收尾部
- sendDownloadFile(filePath,storagePath);
- return;
- }
- else if(token=="197%*CLIENT_RECEIVED*%197"){
- qDebug()<<"客户端已成功接收文件";
- isStart = true;//信号只是个头,不应该继续接收尾部
- return;
- }
- else{
- qDebug()<<"无效token!";
- return;
- }
- filename=targetDir+"\"+filename;//设置文件位置
- file.setFileName(filename);
- qDebug()<<"filename="<<filename;
- bool isOk = file.open(QIODevice::WriteOnly);
- if(false == isOk)//打开失败
- {
- return;
- }
- }
- else//文件的头部信息已经接收
- {
- qDebug()<<"接收尾部===";
- qint64 len = file.write(buf);//将buf中的数据写入file文件,并返回实际写入的字节数。
- if(len>0)
- {
- recvfilesize += len;//累计接收大小
- int percent = ((recvfilesize)*100)/filesize;
- //发出更新进度条的信号
- //qDebug()<<"percent="<<percent;
- emit curPercent(percent);
- }
- if(recvfilesize == filesize)
- {
- //emit recvOver();//接收完毕
- qDebug()<<"接收完毕1";
- file.close();
- isStart = true;
- //通知客户端 接收完毕
- // 文件传输成功后发送文件接收完毕的信息给客户端
- //============================================Token==================================================================
- QString token="197%*SERVER_RECEIVED*%197";
- //============================================Token==================================================================
- QByteArray completionMessage = token.toUtf8();
- completionMessage.append("##");
- tcpSocket->write(completionMessage);
- tcpSocket->waitForBytesWritten(); // 等待数据写入完毕
- }
- else{
- qDebug()<<"recvfilesize != filesize";
- //isStart = true;
- }
- }
- }
- void RecvFile::sendDownloadFile(QString path,QString targetDir)//发送头
- {
- timer = new QTimer(this);
- connect(timer,&QTimer::timeout,[=]()
- {
- //关闭定时器
- timer->stop();
- //发送文件数据
- sendDownloadFileData();
- });
- file.setFileName(path);
- //获取文件信息
- QFileInfo info(path);
- filesize = info.size();//获取文件大小
- filename = info.fileName();//获取文件名
- //============================================Token==================================================================
- QString token="197%*FILE*%197";
- //============================================Token==================================================================
- //只读方式打开文件
- bool isOk = file.open(QIODevice::ReadOnly);
- if(true == isOk)
- {
- //创建文件头信息
- QString head = QString("%1##%2##%3##%4").arg(token).arg(filename).arg(filesize).arg(targetDir);
- //创建文件头信息,格式为"文件名##文件大小",例如 "example.txt##1024"
- //发送头部信息
- qint64 len = tcpSocket->write(head.toUtf8());
- if(len>0)//发送成功
- {
- //防止tcp黏包问题,延时20ms
- timer->start(20);
- }
- else
- {
- //发送失败
- file.close();
- }
- }
- else
- {
- QMessageBox::warning(nullptr,"错位","打开文件失败!");
- return;
- }
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |