【QT学习】13.使用TCP实现文件传输

一。传输文件流程

二。实现

结果:

1. server

server类属性

复制代码
    Ui::Widget *ui;

    QTcpServer* pTcpServer;
    QTcpSocket* pTcpSocket;
    //文件与文件信息
    QFile file;
    QString m_fileName;
    qint64 m_fileSize;  //整个文件大小
    qint64 fileSize;    //当前已经发送的文件大小

    bool isHead;

文件传递

复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("服务器,文件接收端,port:6666");
    ui->progressBar->setValue(0);
    isHead=true;    //接受文件的标识

    //1创建socket
    pTcpServer=new QTcpServer(this);
    //2监听--》udp这里是绑定,ip与port
    pTcpServer->listen(QHostAddress::Any,6666);
    fileSize=0;
    //3等待客户端连接
    connect(pTcpServer,&QTcpServer::newConnection,
            [=](){
            pTcpSocket=pTcpServer->nextPendingConnection();

            QString ip=pTcpSocket->peerAddress().toString();
            quint16 port=pTcpSocket->peerPort();
            QString str=QString("客户端连接服务器成功IP:%1 Port:%2").arg(ip).arg(port);
            ui->textEdit->setText(str);

            //4接受数据
            connect(pTcpSocket,&QTcpSocket::readyRead,
                    [=](){
                    QByteArray buff;
                    buff=pTcpSocket->readAll();

                    if(isHead){//接受文件信息--》创建文件
                        isHead=false;
                        m_fileName=QString(buff).section("--",0,0);
                        m_fileSize=QString(buff).section("--",1,1).toInt();

                        ui->textEdit->append(buff);
                        QString tmp=QString("文件名:%1 文件大小:%2").arg(m_fileName).arg(m_fileSize);
                        ui->textEdit->append(tmp);

                        file.setFileName(m_fileName);
                        bool is=file.open(QIODevice::WriteOnly);
                        if(is){
                            qDebug()<<"创建文件成功";
                        }else{
                            qDebug()<<"创建文件失败";
                        }
                    }
                    else{//接受文件内容
                        qint64 r=file.write(buff);
                        fileSize+=r;
                        //设置进度条
                        ui->progressBar->setValue(100*fileSize/m_fileSize);
                        if(fileSize>=m_fileSize){
                            file.close();
                            QMessageBox::information(this,"文件接受","文件接受完成");
                            pTcpSocket->disconnect();
                            pTcpSocket->close();
                        }
                    }
            });
    });

}

2. client

复制代码
    Ui::Form *ui;

    QTcpSocket* pTcpSocket;

    QFile file;
    QString m_fileName; //文件名
    qint64 m_fileSize;  //文件大小
    qint64 fileSize;    //当前已经发送文件大小

    QTimer timer;       //定时器
    //发送文件内容
    void sendData();

1实现client

复制代码
Form::Form(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form)
{
    ui->setupUi(this);
    setWindowTitle("客户端 文件发送端");
    //1创建socket
    pTcpSocket=new QTcpSocket(this);
    //设置两个按钮不可按下--》不可发送,不可打开文件
    ui->pushButtonSend->setEnabled(false);
    ui->pushButtonOpen->setEnabled(false);
    //2监听
    connect(pTcpSocket,&QTcpSocket::connected,
            [=](){
            ui->textEdit->setText("连接服务器成功");
            ui->pushButtonOpen->setEnabled(true);
    });
    //文件信息发送后,再发送文件内容(定时器)
    connect(&timer,&QTimer::timeout,
            [=](){
            timer.stop();//关掉
            ui->textEdit->append("开始发送数据");
            sendData();
    });
}
void Form::sendData(){
    qint64 r=0;
    char buff[1024];
    while(1){
        r = file.read(buff,1024);//从文件中读取
        if(r<=0) break;
        r = pTcpSocket->write(buff,r);//发给接收端
        if(r <=0 ) break;
        fileSize += r;//累加已经发送的文件大小
    }
    qDebug()<<"文件传递成功";
}

tcp连接

复制代码
void Form::on_pushButtonConnect_clicked()
{
   QString ip=ui->lineEditIP->text();
   quint16 port=ui->lineEditPORT->text().toUInt();
   pTcpSocket->connectToHost(ip,port);
}

打开文件

复制代码
void Form::on_pushButtonOpen_clicked()
{
    QString fileName=QFileDialog::getOpenFileName(this,"打开发送文件","C:/Users/Administrator/Desktop",
                                                  "TXT(*.txt);;"
                                                  "DOC(*.doc,*.doxc);;"
                                                  "MP4(*.mp4);;"
                                                  "ALL(*.*)");
    if(!fileName.isEmpty()){
        m_fileName.clear();
        m_fileSize=0;
        fileSize=0;
        //文件信息
        QFileInfo info(fileName);
        m_fileName=info.fileName();
        m_fileSize=info.size();

        QString str=QString("文件名%1 文件大小%2").arg(m_fileName).arg(m_fileSize);
        ui->textEdit->append(str);

        //打开文件
        file.setFileName(fileName);//注意用带路径的文件名
        bool is=file.open(QIODevice::ReadOnly);
        if(is){
            ui->textEdit->append("准备发送文件路径");
            ui->textEdit->append(fileName);
            ui->pushButtonSend->setEnabled(true);
            ui->pushButtonOpen->setEnabled(false);
        }else{
            qDebug()<<"打开文件失败";
        }
    }else{
        qDebug()<<"获取文件失败";
    }
}

发送文件消息触发

复制代码
void Form::on_pushButtonSend_clicked()
{
    QString fileHead=QString("%1--%2").arg(m_fileName).arg(m_fileSize);
    qint64 ret=pTcpSocket->write(fileHead.toUtf8());
    if(ret>0){
        qDebug()<<"文件发送信息成功";
        timer.start(20);//定时器20ms发送
    }else{
        qDebug()<<"发送文件信息失败";
        file.close();
        ui->pushButtonSend->setEnabled(false);
        ui->pushButtonOpen->setEnabled(true);
    }
}
相关推荐
云上艺旅6 小时前
K8S学习之基础七十四:部署在线书店bookinfo
学习·云原生·容器·kubernetes
你觉得2056 小时前
哈尔滨工业大学DeepSeek公开课:探索大模型原理、技术与应用从GPT到DeepSeek|附视频与讲义下载方法
大数据·人工智能·python·gpt·学习·机器学习·aigc
A旧城以西8 小时前
数据结构(JAVA)单向,双向链表
java·开发语言·数据结构·学习·链表·intellij-idea·idea
无所谓จุ๊บ8 小时前
VTK知识学习(50)- 交互与Widget(一)
学习·vtk
FAREWELL000758 小时前
C#核心学习(七)面向对象--封装(6)C#中的拓展方法与运算符重载: 让代码更“聪明”的魔法
学习·c#·面向对象·运算符重载·oop·拓展方法
吴梓穆8 小时前
UE5学习笔记 FPS游戏制作38 继承标准UI
笔记·学习·ue5
Three~stone8 小时前
MySQL学习集--DDL
数据库·sql·学习
齐尹秦9 小时前
HTML 音频(Audio)学习笔记
学习
瞌睡不来9 小时前
(学习总结32)Linux 基础 IO
linux·学习·io
Moonnnn.9 小时前
运算放大器(四)滤波电路(滤波器)
笔记·学习·硬件工程