QT TCP传输文件+ui

TCPFile

tcp协议传输文件

在这里插入图片描述

TCPFile.pro

QT       += core gui network

clientwidget.h

#include <QWidget>
#include <QTcpSocket>  // 通信套接字
#include <QFile>

private slots:
    void on_pushButton_clicked();

private:
    

    QTcpSocket *tcpSocket;

    QFile file; // 文件对象
    QString fileName; // 文件名字
    qint64 fileSize;  // 文件大小
    qint64 recvSize;  // 已经接收文件的大小

    bool isStart;  // 标志位

widget.h

#include <QTcpServer>  // 监听套接字
#include <QTcpSocket>  // 通信套接字
#include <QFile>
#include <QTimer>

public:
    

    void sendData(); // 发送文件数据

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    

    QTcpServer *tcpServer;
    QTcpSocket *tcpSocket;
    QFile file; // 文件对象
    QString fileName; // 文件名字
    qint64 fileSize;  // 文件大小
    qint64 sendSize;  // 已经发送文件的大小

    QTimer timer;  // 定时器

clientwidget.cpp


#include <QDebug>
#include <QMessageBox>
#include <QHostAddress>

Clientwidget::Clientwidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Clientwidget)
{
    ui->setupUi(this);

    isStart = true;

    tcpSocket = NULL;

    // 分配空间,指定父对象
    tcpSocket = new QTcpSocket(this);

    setWindowTitle("客户端");

    // 进度条
    ui->progressBar->setValue(0);  //  当前值

    connect(tcpSocket, &QTcpSocket::readyRead, [=](){
       // 取出接收内容
        QByteArray buf = tcpSocket->readAll();

        if(true == isStart)
        { // 接收头信息
            isStart = false;

            // 解析头部信息 举例:

            // QString str = "hello##1024";
            // 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";
            }

            // 设置进度条
            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){  // 文件接收完毕

                file.close();
                QMessageBox::information(this, "完成", "文件接收完成");
                // 给服务器发送 接收文件完成的信息
                tcpSocket->write("file done");

                tcpSocket->disconnectFromHost();
                tcpSocket->close();
            }
        }
    });

}

void Clientwidget::on_pushButton_clicked()
{
    // 获取服务器ip和端口
    QString ip = ui->lineEdit->text();
    quint16 port = ui->lineEdit_2->text().toInt();

    // 主动和服务器建立连接
    tcpSocket->connectToHost(QHostAddress(ip), port);
}

widget.cpp


#include <QFileDialog>
#include <QDebug>
#include <QFileInfo>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 监听套接字
    tcpServer = new QTcpServer(this);

    // 监听
    tcpServer->listen(QHostAddress::AnyIPv4, 8888);
    setWindowTitle("服务器 端口8888");

    // 一开始两个按钮都不能按 需要建立连接后才可以按下
    ui->pushButton->setEnabled(false);
    ui->pushButton_2->setEnabled(false);

    // 如果客户端成功和服务器连接
    // tcpServer 会自动触发 newConnection()
    connect(tcpServer, &QTcpServer::newConnection, [=](){
       // 取出建立好连接的套接字
        tcpSocket = tcpServer->nextPendingConnection();
        // 获取对方的ip和端口
        QString ip = tcpSocket->peerAddress().toString();
        quint16 port = tcpSocket->peerPort();

        // qDebug() << port;
        QString temp = QString("[%1:%2]:成功连接").arg(ip).arg(port);
        ui->textEdit->setText(temp);  // 显示到编辑区

        // 成功建立连接后,才可以按钮 选择文件
        ui->pushButton->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();
    });

}

Widget::~Widget()
{
    delete ui;
}

void Widget::sendData()
{
    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();

        ui->pushButton->setEnabled(false);
        ui->pushButton_2->setEnabled(false);
    }
}

// 选择文件按钮
void Widget::on_pushButton_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() << "只读方式打开文件失败";
        }

        // 提示打开文件的路径
        ui->textEdit->append(filePath);

        ui->pushButton->setEnabled(false);
        ui->pushButton_2->setEnabled(true);

    }
    else{
        qDebug() << "选择文件路径出错";
    }
}

// 发送文件按钮
void Widget::on_pushButton_2_clicked()
{
    // 先发送文件头信息  文件名##文件大小
    QString head = QString("%1##%2").arg(fileName).arg(fileSize);
    // 发送头部信息
    qint64  len = tcpSocket->write( head.toUtf8() );
    if(len > 0) {   // 头部信息发送成功
        // 发送真正的文件信息
        // 防止TCP黏包问题 需要通过定时器延时 20ms
        timer.start(20);

    }
    else {
        qDebug() << "头部信息发送失败";
        file.close();
        ui->pushButton->setEnabled(true);
        ui->pushButton_2->setEnabled(false);
    }
}

clientwidget.ui

在这里插入图片描述

widget.ui

在这里插入图片描述

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值