【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);
    }
}
相关推荐
自强的小白1 小时前
vlan(局部虚拟网)
网络·学习
一只乔哇噻1 小时前
java后端工程师进修ing(研一版 || day41)
java·开发语言·学习·算法
知识分享小能手2 小时前
React学习教程,从入门到精通,React 使用属性(Props)创建组件语法知识点与案例详解(15)
前端·javascript·vue.js·学习·react.js·前端框架·vue
知识分享小能手8 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
茯苓gao10 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾11 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
DKPT11 小时前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习
aaaweiaaaaaa11 小时前
HTML和CSS学习
前端·css·学习·html
看海天一色听风起雨落12 小时前
Python学习之装饰器
开发语言·python·学习
speop13 小时前
llm的一点学习笔记
笔记·学习