QT中TCP文件传输

这篇具有很好参考价值的文章主要介绍了QT中TCP文件传输。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


*免责声明:
1、视频来源于传智播客
2、此方法仅提供参考

本文代码根据B站《零基础入门六天学会QT完整版》中的P52和P53,其中视频有缺失,为了造福其他兄弟,在此补上缺失代码


首先需要创建两个类:ServerWidget和ClientWidget类

一、UI文件

1.serverwidget.ui

QT中TCP文件传输

2.clientwidget.ui

QT中TCP文件传输

二、.h文件

1.serverwidget.h

QT中TCP文件传输

2.clientwidget.h

QT中TCP文件传输

三、cpp文件

1.ClientWidget.cpp

#include "clientwidget.h"
#include "ui_clientwidget.h"
#include <QMessageBox>
#include <QHostAddress>
#include <QDebug>

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

    //创建TCP套接字
    tcpSocket = new QTcpSocket(this);

    //设置标题
    setWindowTitle("客户端");

    //如果连接成功
    connect(tcpSocket,&QTcpSocket::connected,
            [=]()
    {
       //初始化数据
        fileName = "";
        fileSize = 0;
        recvSize = 0;
        isFile = false;

        ui->buttonConnect->setEnabled(false);
        ui->textEdit->clear();

        ui->textEdit->append("和服务器连接成功");
    });

    ui->progressBar->setValue(0);

    //当有数据可接收时
    connect(tcpSocket,&QTcpSocket::readyRead,
            [=]()
    {
        QByteArray buf = tcpSocket->readAll();  //一次收8k

        if(false == isFile)//先接受头部信息(第一条数据)
        {
            isFile = true;
            //head # filename # size
            //文件名称
            fileName = QString(buf).section("#",1,1);
            //文件大小
            fileSize = QString(buf).section("#",2,2).toInt();
            qDebug() << fileName << fileSize;

            recvSize = 0;

            file.setFileName(fileName);

            if(false == file.open(QIODevice::WriteOnly)){
                //初始化数据
                fileName = "";
                fileSize = 0;
                recvSize = 0;
                isFile = false;
                QMessageBox::warning(this,"警告","创建文件失败");
                return;
            }

            //设置进度条最大值最小值
            ui->progressBar->setMinimum(0);
            ui->progressBar->setMaximum(fileSize/1024);

            ui->textEdit->append(QString("正在接受文件:\n%1").arg(fileName));

        }

        else//文件数据!!!
        {
            qint64 len = file.write(buf);
            recvSize += len;
            qDebug() << len;
            ui->progressBar->setValue(recvSize/1024);

        }

        if (recvSize == fileSize)
        {
           file.close();  //接收完毕后要记得关闭文件
           ui->buttonConnect->setEnabled(true);
           tcpSocket->disconnectFromHost();  //手动断开连接

           QMessageBox::information(this,"ok","文件接受完毕");
           ui->textEdit->append("文件接受完毕");

        }
    });
}

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

//连接按钮
void ClientWidget::on_buttonConnect_clicked()
{
    ui->progressBar->setValue(0);//设置进度条0

    //初始化操作
    QString ip = ui->lineEditIP->text();
    qint16 port = ui->lineEditPort->text().toInt();
    if(ip.isEmpty() == true || port == 0)
    {
        QMessageBox::warning(this,"警告","ip或端口不能为空");
        return;
    }

    tcpSocket->abort();//取消已有的连接

    //连接服务器!
    tcpSocket->connectToHost(QHostAddress(ip),port);
}

2.ServerWidget.cpp

#include "serverwidget.h"
#include "ui_serverwidget.h"
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QTimer>
#include <QThread>

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

    //创建套接字
    tcpServer = new QTcpServer(this);

    //监听,端口:8888
    bool isOk = tcpServer->listen(QHostAddress::Any,8888);
    if(false == isOk)//监听失败
    {
        QMessageBox::warning(this,"监听","监听失败");
        return;
    }

    //设置标题
    setWindowTitle("服务器:88888");

    //设置按钮(变灰)
    ui->buttonChoose->setEnabled(false);
    ui->buttonSend->setEnabled(false);

    //当有客户端连接时,触发信号:newConnection
    connect(tcpServer,&QTcpServer::newConnection,
            [=]()
            {
                //接收客户端套接字对象,从连接请求中选择一个请求连接(取出套接字)
                tcpSocket = tcpServer->nextPendingConnection();

                //获取对方的ip和port
                QString ip = tcpSocket-> peerAddress().toString();//获取client的ip地址
                quint16 port = tcpSocket->peerPort();//获取client的端口号
                QString str = QString("[%1:%2]和服务器连接成功").arg(ip).arg(port);
                ui->textEdit->setText(str);//设置内容

                //恢复选择按钮状态
                ui->buttonChoose->setEnabled(true);
                QMessageBox::information(this,"允许","连接成功,可以选择文件发送");
            });

    //定时器处理函数
    connect(&timer,&QTimer::timeout,
            [=]()
    {
        this->timer.stop();//关闭定时器
        senFileData();
    });
}


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



//选择文件按钮
void ServerWidget::on_buttonChoose_clicked()
{
    QString path = QFileDialog::getOpenFileName(this,"请选择所要发送的文件","../");
    if(path.isEmpty() == false)
    {
            file.setFileName(path);
            //只读方式打开文件
            bool isOk = file.open(QIODevice::ReadOnly);
            if(false == isOk)//打开文件失败
            {
                QMessageBox::warning(this,"警告","打开文件失败");
                return;
            }
            else
            {
                ui->textEdit->append("发送的文件:");
                ui->textEdit->append(path);

                //初始化数据
                fileName = "";
                fileSize = 0;
                sendSize = 0;

                //获取发送文件的信息
                QFileInfo info(path);
                fileName = info.fileName();
                fileSize = info.size();

                ui->buttonSend->setEnabled(true);//恢复发送文件按钮
                ui->buttonChoose->setEnabled(false);//选择按钮变灰

            }

    }
}

//发送文件按钮
void ServerWidget::on_buttonSend_clicked()
{
    //发送文件按钮变灰
    ui->buttonSend->setEnabled(false);

    //先发送文件头,自定义的数据,不是文件数据
    //先发送头。自定义组包, 文件名#文件大小
    QString buf = QString("head#%1#%2").arg(fileName).arg(fileSize);

    //先发头
    qint64 len = tcpSocket->write(buf.toUtf8().data());
    tcpSocket->waitForBytesWritten();//等待数据发送完毕

    ui->textEdit->append("已经在发送文件!!");

    if(len>0)//如果头部信息发送成功,开始发送文件数据
    {
        //10毫秒后在发送文件数据
        //启动定时器,定时器内容发送文件数据
        //防止tcp黏包问题
        this->timer.start(1000);//为了延时
    }
    else
    {
        file.close();
    }

}

void ServerWidget::senFileData(){

    //发送文件信息
    //发送文件
    qint64 len = 0 ;

    do{
        //每次发送2kb大小的数据,如果剩余的数据不足2kb,就发送剩余数据的大小
        char buf[2*1024]= {0};

        len = 0;
        len=file.read(  buf , sizeof(buf) );        //读数据
        len=tcpSocket->write(buf , len);            //发数据

        //发送数据需要累积
        sendSize += len;

    }while(len>0 );
    //文件数据发送完毕
    if (fileSize == sendSize)
        {
        //QMessageBox::information(this,"ok","文件发送完毕");
        ui->textEdit->append("发送成功");

        file.close();//关闭文件
        //关闭客户端
        tcpSocket->disconnectFromHost();
        tcpSocket->close();
    }
}

3.main.cpp

QT中TCP文件传输


四、运行效果图

QT中TCP文件传输

以上就是视频中TCP文件传输的代码,若有发现错误可以评论指出。文章来源地址https://www.toymoban.com/news/detail-424248.html

到了这里,关于QT中TCP文件传输的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • QT-通过tcp传输文件和文本消息

    在建立连接的基础上增加了发送文件的功能,在接收端和发送端定义了一个枚举类型,用于判别发送的是文件还是文本消息 客户端ui 1.获取端口号和ip地址,进行连接,再次点击即可断开连接 2.点击发送消息按钮,获取文本框内容,将消息发送出去,其中type为文本消息类型

    2024年02月03日
    浏览(28)
  • 网络爬虫使用指南:安全合理,免责声明

    作为一名经验丰富的网络爬虫,我深知在爬取网页数据时可能会遇到一些问题和风险。因此,我特别撰写这篇经验分享来告诉大家如何合理、安全地使用网络爬虫,以及注意事项和免责声明。 一、了解目标网站 在开始爬取之前,首先要对目标网站进行仔细的了解。了解网站

    2024年02月03日
    浏览(77)
  • Qt开发-TCP/IP网络通信(以及文件传输)

    TCP/IP通信(即SOCKET通信)是通过网线将 服务器Server端 和 客户机Client端 进行连接,在遵循ISO/OSI模型的四层层级构架的基础上通过TCP/IP协议建立的通讯。控制器可以设置为服务器端或客户端。 关于TCP/IP协议可详看:TCP/IP协议详解 - 知乎 (zhihu.com) 总的来说,TCP/IP通讯有两个部分

    2024年02月10日
    浏览(39)
  • Qt详解实现TCP文件传输例子(文件下载和上传)附源码

    网络通信我们用的很频繁,如文字,语音,文件,图片等,这个些传输方式都差不多 QT文件传输主要考验对传输的控制,还是需要点逻辑的,文件传输的大致框架如下 先看一下简单例子实现的效果(界面有点丑,重点在于内容):  接下来重点讲一下需要用到哪些东西: 1.数

    2024年02月16日
    浏览(32)
  • ChatGPT Claude Bard 生成式 AI 免责声明

    ChatGPT can make mistakes. Consider checking important information. Claude.ai is in beta release and may display incorrect or harmful information Bard may display inaccurate info, including about people, so double-check its responses. Your privacy Bard

    2024年01月25日
    浏览(29)
  • Qt多线程TCP服务器客户端传输文件

    TCP是面向连接的运输层协议。应用程序在使用TCP协议之前,必须先建立TCP连接。在传送数据完毕后,必须释放已经建立的TCP连接。 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的(一对一)。 TCP提供可靠交付的服务。通过TCP 连接传送的数据,无差错、不丢失、不

    2024年02月13日
    浏览(41)
  • QT下TCP协议实现数据网络传输

    QT开发框架以其跨平台的优势,在全世界IT界如雷贯耳。其封装了功能齐全的各种类,大大的提高了开发者的效率。本篇内容将介绍如何使用QT 6.4.1框架开发服务器和客户端程序,让两端能够首发消息,服务端往客户端发送文件(客户端往服务器发送类似,没有实现)。  说明

    2023年04月08日
    浏览(32)
  • window下使用tcp传输视频(c++)

    ​ 参考链接: tcp传输普通文本 网络编程:基于TCP的socket网络传输视频(C++, python) 由于项目要求,需要使用tcp完成视频的传输,udp其实也可以,但是udp不可靠,怕丢帧。 菜鸟一个,边缝边写,希望抛砖引玉,大家有意见可以评论区见。哈哈哈! tcp相关内容不再赘述,本人

    2023年04月24日
    浏览(18)
  • Qt的TCP传输数据,出现中文乱码的解决方案

    Qt的TCP传输数据中文乱码的问题,可能是由于编码不一致导致的。可以尝试以下方法解决: 在发送数据之前,将中文字符串进行编码转换。例如,将QString类型的中文字符串转换成UTF-8编码的字节数组,可以使用QString的toUtf8()函数,示例代码如下: QString str = \\\"中文字符串\\\"; QB

    2024年02月09日
    浏览(48)
  • JRTP实时音视频传输(2)-使用TCP通信的案例

    环境搭建等参考:JRTP实时音视频传输(1)-必做的环境搭建与demo测试 先将example1拷贝为myclienttcp.cpp和myservertcp.cpp cp example1.cpp myclienttcp.cpp cp example1.cpp myservertcp.cpp 改写jrtplib/JRTPLIB/examples/CMakeLists.txt,添加myclienttcp和myservertcp编译 重新生成Makefile并编译 可以看到成功编译了myclient

    2024年01月18日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包