当前位置: 首页 > news >正文

TCP传输文件

传输文件和传输信息的区别:

  • 传输信息,只是一条数据,传输文件是多条数据
  • 传输信息传输过去一般都会显示,传输文件一般不会显示,一般只是存放在文件中
  • 传输文件需要传输,文件大小和文件名称(不然不知道什么时候结束)

在这里使用的是服务器端发送数据,客户端接收数据。

为了在本地测试把服务器端和客户端分项目编写,方便在一台电脑上测试。

总的代码会在文件最后给出

目录显示:

  • File_Tcp为服务器端,发送文件
  • File_Tcp_Socket 为客户端,接收文件(创建的时候忘记该类名了,这里就使用widget了)

服务器端的编写

发送的规则:

  • 先发送,文件的参数,文件大小和文件名
  • 然后再发送,文件的内容

创建一个项目;

pro文件中添加:

QT +=network

ui界面添加以下控件:

tcp_server.h文件内容解析

1.添加以下头文件:

#include<QTcpServer>
#include<QMessageBox>
#include<QFile>
#include<QMessageBox>
#include<QTcpSocket>
#include<QHostAddress>
#include<QNetworkInterface>
#include<QFileDialog>
#include<QDataStream>
#include<QFileInfo>

2.添加私有成员:

private:QTcpServer *server;//服务器端QTcpSocket *socket;//套接字QString FilePathName;//文件路径QString FileName;//文件名QFile * LocalFile;//文件指针,打开需要传输的文件qint64 FileSize=0;//文件总大小qint64 TFSize=0;//已传输的大小qint64 ToBeSize=0;//未传输的数据qint64 payloadSize=64*1024;//有效的载荷,64KBQByteArray block;//缓存,用来临时存储需要发送的信息

3.槽函数

private slots:void on_pushButton_3_clicked();void on_pushButton_clicked();void on_pushButton_2_clicked();void on_pushButton_4_clicked();//上面是ui界面转到槽生成的信号void Send_File(qint64 num);//用来传输文件内容

4.事件和其他函数:

protected:void closeEvent(QCloseEvent *event);//重写关闭事件QString getIp();//获取IP

tcp_server.cpp文件内容解析

1.构造函数中的内容

    server=new QTcpServer(this);//QTcpServer的初始化QString Ip=getIp();//获取本机的IP地址ui->lineEdit_4->setText(tr("%1").arg(Ip));//再主机的lineEdit中显示IP地址ui->lineEdit_5->setText("6666");//设置端口号socket=nullptr;//初始化QTcpSocketconnect(server,&QTcpServer::newConnection,[=]()//当有新的连接时{QMessageBox::information(this,"提示信息","已有新连接",QMessageBox::Ok);socket=new QTcpSocket(this);//套接字socket=server->nextPendingConnection();//获取套接字});//实现可以多次传输,当文件地址改变时,这些参数都置为0connect(ui->lineEdit,&QLineEdit::textChanged,[=]()//{FileSize=0;//文件总大小TFSize=0;//已传输的大小ToBeSize=0;//未传输的数据ui->lineEdit_2->setText("");ui->lineEdit_3->setText("");});

2.getIP()函数的实现

QString TCP_Server::getIp()//获取IP
{QList<QHostAddress> addss=QNetworkInterface::allAddresses();//获取全部地址foreach(QHostAddress add,addss)//遍历这些地址{if(add.protocol()==QAbstractSocket::IPv4Protocol)//如果地址为IVP4的话{return add.toString();//返回该地址}}return 0;//没有的话返回0
}

3.监听的实现:

void TCP_Server::on_pushButton_3_clicked()//监听
{if(!server->listen(QHostAddress(ui->lineEdit_4->text()),ui->lineEdit_5->text().toInt()));//如果监听失败{return;}
}

4.获取文件名的实现:

void TCP_Server::on_pushButton_clicked()//获取文件名
{FilePathName=QFileDialog::getOpenFileName(this);//获取路径if(!FilePathName.isEmpty())//文件名不为空{QFileInfo fi(FilePathName);//创建一个文件信息对象FileName=fi.fileName();//获取文件名ui->lineEdit->setText(FilePathName);//放置文件名}}

5.取消的实现:

void TCP_Server::on_pushButton_4_clicked()//取消
{if(server->isListening())//如果正在监听{server->close();if(LocalFile->isOpen()){LocalFile->close();}socket->abort();//断开连接}
}

6.重写关闭事件:

void TCP_Server::closeEvent(QCloseEvent *event)//重写关闭事件
{on_pushButton_4_clicked();//取消close();
}

7.发送的实现,(发送文件的一些参数)

void TCP_Server::on_pushButton_2_clicked()//发送文件信息
{LocalFile=new QFile(FilePathName);//打开该文件if(!LocalFile->open(QFile::ReadOnly))//当文件打不开{QMessageBox::information(this,"提示信息","发送失败",QMessageBox::Ok);return;}//当接收完一次数据后,执行传输文件的操作,直到传输完connect(socket,SIGNAL(bytesWritten(qint64)),this,SLOT(Send_File(qint64)));//使用缓存FileSize=LocalFile->size();//获取文件的大小QDataStream Ds(&block,QIODevice::WriteOnly);//创建一个数据流Ds.setVersion(QDataStream::Qt_5_9);//设置版本号;Ds<<qint64(0)<<qint64(0)<<FileName;//将数据写入流中FileSize+=block.size();//获取流中数据的大小Ds.device()->seek(0);//回到开头Ds<<FileSize<<qint64(block.size()-sizeof(qint64)*2);//数据的总长度和文件长度//把文件头传输出去,同时修改待发送的字节数ToBeSize=FileSize-socket->write(block);block.resize(0);//把缓存置0,以便下次使用}

这里主要解释一下

//当接收完一次数据后,执行传输文件的操作,直到传输完connect(socket,SIGNAL(bytesWritten(qint64)),this,SLOT(Send_File(qint64)));

在这里,使用新版的信号于槽,会报错,不知道什么原因。

bytesWritten(qint64):每次将数据有效负载写入设备的当前写入通道时,都会发出此信号。会返回写入的字节数。

当写入通道时,使用Send_File(qint64)来统计字节数

8.Send_File(qint64)的实现

  1. 首先要统计数据
  2. 判断数据,如果还有未传输的数据,继续传输
  3. 在显示总的文件大小和已传输的大小
  4. 如果已发送的文件大小==总文件大小,关闭文件关闭服务器,提示传输完成
void TCP_Server::Send_File(qint64 num)//传输文件数据
{qApp->processEvents();//防止传输文件时页面冻结TFSize+=(int)num;//更新已传输的数据大小if(ToBeSize>0)//如果未传输的数据大于0{//当剩下的数据小于payloadSize时,优先使用更小的值block=LocalFile->read(qMin(ToBeSize,payloadSize));//读取数据ToBeSize-=(int)socket->write(block,block.size());//发送并更新数据大小block.resize(0);//清空缓存}else{LocalFile->close();}ui->lineEdit_3->setText(tr("%1").arg(FileSize/(1024*1024))+"MB");//总的数据量ui->lineEdit_2->setText(tr("%1").arg(TFSize/(1024*1024))+"MB");//已传输的数据if(FileSize==TFSize){LocalFile->close();//关闭文件server->close();//关闭服务器QMessageBox::information(this,"提示信息","传输完成",QMessageBox::Ok);}}

main函数:

#include "tcp_server.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);TCP_Server w;w.show();return a.exec();
}

服务器端的搭建 

  • 接收文件时,需要判断是否接受了文件信息

  • 接受了话再接受文件的内容

创建一个项目:

pro文件中添加:

QT  +=network

ui界面中添加以下控件:

 widget.h文件的内容解析

1.添加以下头文件 

#include<QTcpSocket>
#include<QDataStream>
#include<QMessageBox>
#include<QHostAddress>
#include<QFile>

2.添加私有成员

    QTcpSocket *socket;//套接字QFile *file;//文件指针qint64 RCDsize;//接收的数据qint64 ToBoSize;//未接收的数据qint64 Filesize;//文件总大小qint64 Allsize;//总大小QString FileName;//文件名称QByteArray inblock;//缓存

3.槽函数

private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();
//以上未ui界面中转到槽实现void readData();//读取数据

4.重写事件

protected:void closeEvent(QCloseEvent *event);//重写关闭事件

widget.cpp文件的内容解析:

1.构造函数

    socket=new QTcpSocket(this);ui->lineEdit_2->setText("6666");//设置端口号未6666ToBoSize=0;Filesize=0;RCDsize=0;connect(socket,&QTcpSocket::readyRead,this,&Widget::readData);//读取数据

2.连接的实现

void Widget::on_pushButton_clicked()//连接
{
socket->abort();//断开已有连接//创建连接socket->connectToHost(QHostAddress(ui->lineEdit->text()),ui->lineEdit_2->text().toInt());
}//QHostAddress(ui->lineEdit->text())为地址
//ui->lineEdit_2->text().toInt()为端口号

3.取消的实现

void Widget::on_pushButton_2_clicked()//取消
{socket->abort();//断开连接if(file->isOpen()){file->close();}}

4.重写关闭事件

void Widget::closeEvent(QCloseEvent *event)
{socket->abort();if (file->isOpen())file->close();close();
}

5.读取数据的实现

void Widget::readData()//读取数据
{QDataStream in(socket);//流读取数据in.setVersion(QDataStream::Qt_5_9);if(RCDsize<=sizeof(qint64)*2){if((socket->bytesAvailable()>=sizeof(qint64)*2)&&(Filesize==0)){in>>Allsize>>Filesize;//读取资源的大小,文件的大小RCDsize+=sizeof(qint64)*2;//更新读取的数据}if((socket->bytesAvailable()>=Filesize)&&(Filesize!=0)){in>>FileName;//读取文件名称file=new QFile(FileName);//打开文件ui->lineEdit_3->setText(QString("%1").arg(FileName));RCDsize+=Filesize;//更新读取的数据if(!file->open(QFile::WriteOnly)){QMessageBox::information(this,"提示信息","无法读取文件");return;}}else{return;}}if(RCDsize<Allsize)//如果接受的数据小于总数据,继续接受{RCDsize+=socket->bytesAvailable();inblock=socket->readAll();file->write(inblock);inblock.resize(0);}//更新显示的数据ui->lineEdit_4->setText(QString("%1").arg(RCDsize/(1024*1024))+"MB");ui->lineEdit_5->setText(QString("%1").arg(Allsize/(1024*1024))+"MB");if(RCDsize==Allsize)//如果接受的数据等于总数据,传输完成{file->close();socket->close();QMessageBox::information(this,"提示信息","接收完成",QMessageBox::Ok);//将数据清空以便下次使用file=nullptr;//文件指针RCDsize=0;//接收的数据ToBoSize=0;//未接收的数据Filesize=0;//文件总大小Allsize=0;//总大小FileName="";//文件名称inblock=0;//缓存}
}

运行结果:

  • 先运行服务器端,再运行客户端
  • 客户端和服务器端都输入IP和端口号
  • 服务器端选择文件
  • 点击发送

1.输入主机和端口号 

 2.点击连接,然后点击监听

 3.选择文件点击发送

数据太小所以0MB

注意:传输完会断开连接,所以还需要点击连接再点击监听 

 源码已发出:

QtTcp传输文件(简易)-C++文档类资源-CSDN文库

相关文章:

TCP传输文件

传输文件和传输信息的区别&#xff1a; 传输信息&#xff0c;只是一条数据&#xff0c;传输文件是多条数据传输信息传输过去一般都会显示&#xff0c;传输文件一般不会显示&#xff0c;一般只是存放在文件中传输文件需要传输&#xff0c;文件大小和文件名称&#xff08;不然不知…...

vue3:加载本地图片等静态资源

背景 在我们用 vue2 webpack 的时候&#xff0c;加载图片资源是这样用的&#xff1a; <img :src"require(/assets/test.png)" />这样打包后就会触发 file-loader 打包图片资源&#xff0c;在 dist 文件夹中就可以看到这个图片&#xff08;如果图片较小会打包…...

工作记录------数据库group_concat函数长度问题

工作记录------group_concat函数长度问题 背景&#xff1a;页面在数据展示时&#xff0c;报错&#xff0c;错误显示&#xff1a;String index out of range: -1 异常信息 java.lang.StringIndexOutOfBoundsException: String index out of range: -1at java.lang.String.sub…...

Python基础语法

1 编程环境 1.1 编译环境 pycharmpython/anaconda 1.2 环境设置 File -> settings -> Project interpreter -> 1.3 Hello world 2 条件判断 2.1 例题 【题1】输入一个年份&#xff0c;判断是否是闰年 ①能被4整除&#xff0c;但不能被100整除; ②能被400整…...

windows环境下安装Nginx及常用操作命令

windows环境下安装Nginx及常用操作命令nginx基本概述基本用途nginx安装nginx基本概述 Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器。基本用途 nginx是一个轻量级高并发服务器&#xff0c;而tomcat并不是。nginx一般被用来做反向代理&#xff0c;将请求转发到应用…...

python excel数据处理?

前段时间做了个小项目&#xff0c;帮个海洋系的教授做了个数据处理的软件。基本的功能很简单&#xff0c;就是对Excel里面的一些数据进行过滤&#xff0c;统计&#xff0c;对多个表的内容进行合并等。之前没有处理Excel数据的经验&#xff0c;甚至于自己都很少用到Excel。记得《…...

Hudi-集成Flink

文章目录集成Flink环境准备sql-client方式启动sql-client插入数据查询数据更新数据流式插入code 方式环境准备代码类型映射核心参数设置去重参数并发参数压缩参数文件大小Hadoop参数内存优化读取方式流读&#xff08;Streaming Query&#xff09;增量读取&#xff08;Increment…...

重新认识 React Hooks useContext

通常来说,React 数据的传递方式都是一层一层把资料 props 传到子层的 就算第二层(Function Component)、第三层(Button Group Compontn) 根本没有用到这个资料,但是为了传到最底层(button) ,每一层还是必须要传props // App.js const App = () => {const [dark, setDark…...

数据库(2)--加深对统计查询的理解,熟练使用聚合函数

一、内容要求 利用sql建立学生信息数据库&#xff0c;并定义以下基本表&#xff1a; 学生&#xff08;学号&#xff0c;年龄&#xff0c;性别&#xff0c;系号&#xff09; 课程&#xff08;课号&#xff0c;课名&#xff0c;学分&#xff0c;学时&#xff09; 选课&#xff0…...

stm32f407探索者开发板(十五)——NVIC中断优先级管理

文章目录零、前言一、NVIC中断优先级分组1.1 中断的管理方法1.2 抢占优先级&相应优先级的区别1.3 举例1.4 特别说明1.5 中断优先级分组函数二、NVIC中断优先级设置2.1 中断设置相关寄存器2.2 中断设置优先级2.2.1 中断优先级控制的寄存器组 IP[240]2.2.2 中断使能寄存器组 …...

【Azure 架构师学习笔记】-Azure Logic Apps(6)- Logic Apps调用ADF

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Logic Apps】系列。 接上文【Azure 架构师学习笔记】-Azure Logic Apps&#xff08;5&#xff09;- 标准和使用量类型的区别 前言 Logic Apps 和 ADF 的搭配使用是常见的组合&#xff0c;它们可以互相弥补各自的不足和…...

python随机获取列表中某一元素

1、利用Python中的random模块中的choice方法 random.choice()可以从任何序列&#xff0c;比如list列表中&#xff0c;选取一个随机的元素返回&#xff0c;可以用于字符串、列表、元组等。 import random arr[1,2,3,4,5,6] print(random.choice(arr))2、利用Python中的random模…...

Nacos微服务笔记

Nacos安装Nacos 的 Github&#xff08;Tags alibaba/nacos GitHub&#xff09;下载我们所需的 Nacos 版本&#xff0c;可以选择 windows 或者 Linux。 进入官网&#xff0c;选择合适版本&#xff0c;tar.gz为linux版本&#xff0c;zip为windows版本。下载并解压 nacos-server…...

MAC文件误删怎么办?mac数据恢复,亲测很好用的方法

电脑文件误删&#xff0c;应该很多人都经历过。之前分享了很多关于Windows电脑文件误删如何恢复的方法&#xff0c;那么MAC电脑文件误删该怎么办&#xff1f;有什么好方法可以使得mac数据恢复回来吗&#xff1f;下面就给大家分享一些亲测好用的方法&#xff01; 一、MAC电脑的文…...

机械革命z2黑苹果改造计划第二番-MacOS实用软件渗透工具

机械革命z2黑苹果改造计划第二番-实用软件 Mac实用工具 这是旧电脑改造计划的第二篇&#xff0c;就是安装一些常用软件和一些渗透测试工具&#xff0c;武装灵魂成为真正的生产力工具 首先推荐一个网站&#xff0c;www.mactools.app&#xff0c;这个软件里边有大多数常用的软…...

【LeetCode】每日一题(4)

目录 题目&#xff1a;1124. 表现良好的最长时间段 - 力扣&#xff08;Leetcode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 写在最后&#xff1a; 题目&#xff1a;1124. 表现良好的最长时间…...

Linux内核移植:内核的启动过程分析、启动配置与rootfs必要文件

Linux内核移植&#xff1a;内核的启动过程、启动配置与rootfs必要文件一、启动过程二、启动配置&#xff08;一&#xff09;SysV初始化&#xff08;二&#xff09;systemd初始化三、rootfs中的启动配置文件1、inittab2、/etc/init.d/rcS 脚本3、fstab4、profile 文件5、其他文件…...

【代码随想录训练营】【Day14】第六章|二叉树|理论基础|递归遍历|迭代遍历|统一迭代

理论基础 二叉树的定义形式有&#xff1a;节点指针和数组 在数组中&#xff0c;父节点的下标为i&#xff0c;那么其左孩子的下标即i*21&#xff0c;右孩子的下标即为i*22 二叉树的常见遍历形式有&#xff1a;前序遍历、后序遍历、中序遍历和层序遍历 前序遍历&#xff1a;二…...

AXI-Stream 学习笔记

参考 https://wuzhikai.blog.csdn.net/article/details/121326701 https://zhuanlan.zhihu.com/p/152283168 AXI4 介绍 AXI4 是ARM公司提出的一种片内总线&#xff0c;描述了主从设备之间的数据传输方式。主要有AXI4_LITE、AXI4_FULL、AXI4_STREAM三种。 AXI4_LITE&#xff1…...

【Linux】程序进程地址空间

文章目录程序地址空间进程地址空间程序地址空间 在Linux下,这种地址叫做 虚拟地址, 我们在用C/C语言所看到的地址,全部都是虚拟地址&#xff01;物理地址,用户一概看不到,由OS统一管理 问:C/C程序地址空间是内存吗? -> 根本就不是内存&#xff01; 是进程虚拟地址空间 堆栈…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...