【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);
    }
}
相关推荐
Chef_Chen4 小时前
从0开始学习R语言--Day18--分类变量关联性检验
学习
键盘敲没电5 小时前
【IOS】GCD学习
学习·ios·objective-c·xcode
海的诗篇_5 小时前
前端开发面试题总结-JavaScript篇(一)
开发语言·前端·javascript·学习·面试
AgilityBaby5 小时前
UE5 2D角色PaperZD插件动画状态机学习笔记
笔记·学习·ue5
AgilityBaby5 小时前
UE5 创建2D角色帧动画学习笔记
笔记·学习·ue5
武昌库里写JAVA7 小时前
iview Switch Tabs TabPane 使用提示Maximum call stack size exceeded堆栈溢出
java·开发语言·spring boot·学习·课程设计
一弓虽8 小时前
git 学习
git·学习
Moonnnn.10 小时前
【单片机期末】串行口循环缓冲区发送
笔记·单片机·嵌入式硬件·学习
viperrrrrrrrrr711 小时前
大数据学习(131)-Hive数据分析函数总结
大数据·hive·学习
fen_fen11 小时前
学习笔记(26):线性代数-张量的降维求和,简单示例
笔记·学习·算法