100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Qt下Tcp传输文件

Qt下Tcp传输文件

时间:2023-05-04 02:03:30

相关推荐

Qt下Tcp传输文件

Qt下Tcp传输文件

文章目录

Qt下Tcp传输文件1.服务端2.客户端

1.服务端

//ServerWidgets.h#ifndef SERVERWIDGET_H#define SERVERWIDGET_H#include <QWidget>#include <QTcpServer> //监听套接字#include <QTcpSocket> //通信套接字#include <QFile>#include <QTimer>namespace Ui {class ServerWidget;}class ServerWidget : public QWidget{Q_OBJECTpublic:explicit ServerWidget(QWidget *parent = 0);~ServerWidget();void sendData(); //发送文件数据private slots:void on_buttonFile_clicked();void on_buttonSend_clicked();private:Ui::ServerWidget *ui;QTcpServer *tcpServer; //监听套接字QTcpSocket *tcpSocket; //通信套接字QFile file; //文件对象QString fileName; //文件名字qint64 fileSize; //文件大小qint64 sendSize; //已经发送文件的大小QTimer timer; //定时器};//ServerWidgets.cpp#endif // SERVERWIDGET_H#include "serverwidget.h"#include "ui_serverwidget.h"#include <QFileDialog>#include <QDebug>#include <QFileInfo>ServerWidget::ServerWidget(QWidget *parent) :QWidget(parent),ui(new Ui::ServerWidget){ui->setupUi(this);//监听套接字tcpServer = new QTcpServer(this);//监听tcpServer->listen(QHostAddress::Any, 8888);setWindowTitle("服务器端口为:8888");//两个按钮都不能按ui->buttonFile->setEnabled(false);ui->buttonSend->setEnabled(false);//如果客户端成功和服务器连接//tcpServer会自动触发 newConnection()connect(tcpServer, &QTcpServer::newConnection,[=](){//取出建立好连接的套接字tcpSocket = tcpServer->nextPendingConnection();//获取对方的ip和端口QString ip = tcpSocket->peerAddress().toString();quint16 port = tcpSocket->peerPort();QString str = QString("[%1:%2] 成功连接").arg(ip).arg(port);ui->textEdit->setText(str); //显示到编辑区//成功连接后,才能按选择文件ui->buttonFile->setEnabled(true);connect(tcpSocket, &QTcpSocket::readyRead,[=](){//取客户端的信息QByteArray buf = tcpSocket->readAll();if(QString(buf) == "file done"){//文件接收完毕ui->textEdit->append("文件发送完毕");file.close();//断开客户端端口tcpSocket->disconnectFromHost();tcpSocket->close();}});});connect(&timer, &QTimer::timeout,[=](){//关闭定时器timer.stop();//发送文件sendData();});}ServerWidget::~ServerWidget(){delete ui;}//选择文件的按钮void ServerWidget::on_buttonFile_clicked(){QString filePath = QFileDialog::getOpenFileName(this, "open", "../");if(false == filePath.isEmpty()) //如果选择文件路径有效{fileName.clear();fileSize = 0;//获取文件信息QFileInfo info(filePath);fileName = info.fileName(); //获取文件名字fileSize = info.size(); //获取文件大小sendSize = 0; //发送文件的大小//只读方式打开文件//指定文件的名字file.setFileName(filePath);//打开文件bool isOk = file.open(QIODevice::ReadOnly);if(false == isOk){qDebug() << "只读方式打开文件失败 106";}//提示打开文件的路径ui->textEdit->append(filePath);ui->buttonFile->setEnabled(false);ui->buttonSend->setEnabled(true);}else{qDebug() << "选择文件路径出错 118";}}//发送文件按钮void ServerWidget::on_buttonSend_clicked(){ui->buttonSend->setEnabled(false);//先发送文件头信息 文件名##文件大小QString head = QString("%1##%2").arg(fileName).arg(fileSize);//发送头部信息qint64 len = tcpSocket->write( head.toUtf8() );if(len > 0)//头部信息发送成功{//发送真正的文件信息//防止TCP黏包//需要通过定时器延时 20 mstimer.start(20);}else{qDebug() << "头部信息发送失败 142";file.close();ui->buttonFile->setEnabled(true);ui->buttonSend->setEnabled(false);}}void ServerWidget::sendData(){ui->textEdit->append("正在发送文件……");qint64 len = 0;do{//每次发送数据的大小char buf[4*1024] = {0};len = 0;//往文件中读数据len = file.read(buf, sizeof(buf));//发送数据,读多少,发多少len = tcpSocket->write(buf, len);//发送的数据需要累积sendSize += len;}while(len > 0);////是否发送文件完毕//if(sendSize == fileSize)//{// ui->textEdit->append("文件发送完毕");// file.close();// //把客户端端口// tcpSocket->disconnectFromHost();// tcpSocket->close();//}}

2.客户端

//ClientWidgets.h#ifndef CLIENTWIDGET_H#define CLIENTWIDGET_H#include <QWidget>#include <QTcpSocket>#include <QFile>namespace Ui {class ClientWidget;}class ClientWidget : public QWidget{Q_OBJECTpublic:explicit ClientWidget(QWidget *parent = 0);~ClientWidget();private slots:void on_buttonConnect_clicked();private:Ui::ClientWidget *ui;QTcpSocket *tcpSocket;QFile file; //文件对象QString fileName; //文件名字qint64 fileSize; //文件大小qint64 recvSize; //已经接收文件的大小bool isStart; //标志位,是否为头部信息};#endif // CLIENTWIDGET_H//ClientWidgets.cpp#include "clientwidget.h"#include "ui_clientwidget.h"#include <QDebug>#include <QMessageBox>#include <QHostAddress>ClientWidget::ClientWidget(QWidget *parent) :QWidget(parent),ui(new Ui::ClientWidget){ui->setupUi(this);tcpSocket = new QTcpSocket(this);isStart = true;ui->progressBar->setValue(0); //当前值setWindowTitle("客户端");connect(tcpSocket, &QTcpSocket::readyRead,[=](){//取出接收的内容QByteArray buf = tcpSocket->readAll();if(true == isStart){//接收头isStart = false;//解析头部信息 QString buf = "hello##1024"//QString str = "hello##1024#mike";// str.section("##", 0, 0)//初始化//文件名fileName = QString(buf).section("##", 0, 0);//文件大小fileSize = QString(buf).section("##", 1, 1).toInt();recvSize = 0; //已经接收文件大小//打开文件//关联文件名字file.setFileName(fileName);//只写方式方式,打开文件bool isOk = file.open(QIODevice::WriteOnly);if(false == isOk){qDebug() << "WriteOnly error 49";tcpSocket->disconnectFromHost(); //断开连接tcpSocket->close(); //关闭套接字return; //如果打开文件失败,中断函数}//弹出对话框,显示接收文件的信息QString str = QString("接收的文件: [%1: %2kb]").arg(fileName).arg(fileSize/1024);QMessageBox::information(this, "文件信息", str);//设置进度条ui->progressBar->setMinimum(0); //最小值ui->progressBar->setMaximum(fileSize/1024); //最大值ui->progressBar->setValue(0); //当前值}else //文件信息{qint64 len = file.write(buf);if(len >0) //接收数据大于0{recvSize += len; //累计接收大小qDebug() << len;}//更新进度条ui->progressBar->setValue(recvSize/1024);if(recvSize == fileSize) //文件接收完毕{//先给服务发送(接收文件完成的信息)tcpSocket->write("file done");QMessageBox::information(this, "完成", "文件接收完成");file.close(); //关闭文件//断开连接tcpSocket->disconnectFromHost();tcpSocket->close();}}});}ClientWidget::~ClientWidget(){delete ui;}void ClientWidget::on_buttonConnect_clicked(){//获取服务器的ip和端口QString ip = ui->lineEditIP->text();quint16 port = ui->lineEditPort->text().toInt();//主动和服务器连接tcpSocket->connectToHost(QHostAddress(ip), port);isStart = true;//设置进度条ui->progressBar->setValue(0);}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。