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文库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/57204.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【计算机网路】一个简单的chat程序,并能互传文件(Python)

前言 这个实验已经做了一个多月了&#xff0c;本来打算把程序功能完善一下再分享出来&#xff0c;无奈最近太忙了&#xff0c;又怕改来改去又改崩了就迟迟未改。最近终于把想学了好久的Git学了&#xff0c;就把这个代码传到了Github上。后续如果不出意外的话会继续完善&#x…

数字 IC 设计、FPGA 设计秋招笔试题目、答案、解析(4)2022 乐鑫数字芯片提前批笔试

单选题 1、以下关于 System Verilog 的描述&#xff0c;正确的是&#xff08; &#xff09; A. sv 中可以用 logic 代替 Verilog 中的 wire 和 reg 类型 B. sv 中&#xff0c; 定义成 reg 的信号会被综合成触发器 C. sv 中的 function 语言不可被综合 D. 其他都不正确 …

数字 IC 设计职位经典笔/面试题(二)

共100道经典笔试、面试题目&#xff08;文末可全领&#xff09; FPGA 中可以综合实现为 RAM/ROM/CAM 的三种资源及其注意事项&#xff1f; 三种资源&#xff1a;BLOCK RAM&#xff0c;触发器&#xff08;FF&#xff09;&#xff0c;查找表&#xff08;LUT&#xff09;&#xf…

数字IC设计工程师笔试面试经典100题-有答案

转自知乎答主ictown_数字IC设计工程师笔试面试经典100题-有答案-陈恩 1&#xff1a;什么是同步逻辑和异步逻辑&#xff1f;&#xff08;汉王&#xff09; 同步逻辑是时钟之间有固定的因果关系。异步逻辑是各时钟之间没有固定的因果关系。 同步时序逻辑电路的特点&#xff1a;各…

汇顶2018年 IC校招笔试题目

前言 后面,打算整理下数字ic笔试面试题目,希望以此为出发点,补充知识点!声明:个人觉得,学习期间,基本上都是知识的搬运,所以本博客所有内容都可以被大家引用!为了大家方便引用,博客内的图片都没有加博客的水印(除非不是自己的或者没看到)!这篇文章会基于下面这些文…

请收下这份数字IC面试超强攻略!(内附大厂面试题目)

2022年马上就要结束了&#xff0c;想必今年有很多同学也已经感受到IC行业的门槛在不断提升&#xff0c;这一点尤其在面试的过程中感受明显。 前两年的时候&#xff0c;面试官有可能问一些比较简单的问题就能通过&#xff0c;今年可就没那么简单了&#xff0c;必须提前做好相关…

数字IC笔试题3

目录 1.一个八位D/A转换器最小电压增量为0.01V&#xff0c;当输10011100时&#xff0c;输出电压为&#xff08;D&#xff09;V 2.下述概念中不属于面向对象这种编程范畴的是&#xff08;D&#xff09; 3.组合逻辑电路通常由&#xff08;B&#xff09;组合而成 4.三极管作为…

数字IC笔试题4

目录 1.[单选题]下列电路中属于时序逻辑电路的是&#xff08;B&#xff09; 2.[单选题]关于同步设计描述错误的是&#xff08;D&#xff09; 3.[多选题]下面哪种措施不能减少亚稳态影响&#xff08;CD&#xff09; 4.[单选题]状态机没有冗余状态时&#xff0c;可以不写defa…

海康威视 2024届 数字逻辑设计 实习笔试分析

说明 记录一下 5月11日晚&#xff0c;做的海康威视的一场笔试。分享给需要的IC人。 岗位&#xff1a;数字逻辑设计工程师&#xff08;浙江 杭州&#xff09; 转载需要本人同意&#xff01; 我的见解不一定都是准确的&#xff0c;欢迎评论区交流指正~~ 单选题 1、&#xff…

数字IC设计/FPGA工程师秋招面经

秋招面经 秋招总结迷茫期低谷期兴奋期秋招面试常问问题投递公司学习的FPGA课程总结 秋招总结 已经一个多月没更新博客了&#xff0c;并不是因为博主的只是储备量空了&#xff0c;而是因为我去准备秋招去了&#xff0c;接下来将会恢复博客的更新&#xff0c;速度不会太快&#…

数字IC设计工程师笔试面试经典100题

数字IC设计工程师笔试面试经典100题 https://blog.csdn.net/qq_41394155/article/details/89349935 ASIC–模拟版图工程师 https://blog.csdn.net/qq_41394155/article/details/89208062 ASIC–DFT可测性设计工程师 https://blog.csdn.net/qq_41394155/article/details/8836502…

数字IC笔试题1

目录 单选 1.关于亚稳态的描述错误的是&#xff08;A&#xff09; 2.一段程序如下&#xff0c;请问在45这个时刻上&#xff0c;A B的值各是多少&#xff08;B&#xff09; 3.下列关于综合的说法哪项是不正确的&#xff08;B&#xff09; 4.当功能覆盖率&#xff08;Functi…

数字IC笔试面试常考问题及答案汇总(内含各岗位大厂题目)

经历了无数的笔试面试之后&#xff0c;不知道大家有没有发现数字IC的笔试面试还是有很多共通之处和规律可循的。所以一定要掌握笔试面试常考的问题。 数字IC笔试面试常考问题及答案汇总&#xff08;文末可领全部哦~&#xff09; 验证方向&#xff08;部分题目&#xff09; Q1…

数字IC笔试/面试题

1、什么是同步逻辑和异步逻辑&#xff1f; 同步逻辑是时钟之间有固定的因果关系。异步逻辑是各时钟之间没有固定的因果关系。 同步时序逻辑的特点&#xff1a;各触发器的时钟端全部连接在一起&#xff0c;并接在系统的时钟端&#xff0c;只有当时钟脉冲到来时&#xff0c;电路…

数字IC笔试面试常考问题及答案

来源&#xff1a;知乎 链接&#xff1a;https://zhuanlan.zhihu.com/p/261298869 基础知识 原理务必理解透彻。 锁存器的结构-DFF的结构-建立保持时间-亚稳态-STA-CDC。 亚稳态的成因&#xff0c;危害&#xff0c;解决方法。 建立保持时间的计算&#xff0c;违例的Fix&#x…

3D建模除了日常工作,私下还可以赚外快哦,分分钟嗨赚

学习了游戏建模&#xff0c;肯定是想赚些外快的&#xff0c;可是有哪些地方可以提供这些方便呢&#xff1f;接下来陌陌就来说说了 APP和网站 八戒网&#xff1a;一个比较老的网站&#xff0c;会有一些企业发单&#xff0c;有很多任务&#xff0c;如果能力够不仅能赚取还能给对…

网上赚钱并不适合所有人!你为何没有在网上赚到钱!

为何100个人在网上开端挣钱&#xff0c;最后能挣钱的不到10个人呢&#xff1f;其实网上现在挣钱早已不是早期那么简略了&#xff01;互联网最开端也许是为了把各个地方的人链接在一起&#xff0c;可是不知道从什么时候开端互联网上的人逐渐形成了一个集体然后再到一个圈子。 ​…

飞迈阁带你了解网上赚钱

中国互联网的发展近20年左右&#xff0c;网兼也曾经有过非常多的值得很多人回忆与唠嗑的时​代&#xff0c;每个时代都存在着变富的人&#xff0c;在这些人的背后有的是沧桑&#xff0c;有的是肮脏&#xff0c;网兼就是如此&#xff0c;它本来就差不多是一个毁誉参半的圈子。 当…

AI绘画美女项目成功案例分享:3种变现方式让你赚翻!

的“真人AI绘画美女项目”是指使用人工智能技术绘制美女人脸的项目。这些图片通常呈现出高度的美感和完美的外貌&#xff0c;很难分辨其真实性。这类项目在抖音、小红书等社交平台上备受欢迎&#xff0c;吸引了大量的粉丝和点赞&#xff0c;尽管有人认识到这些图片是使用AI绘制…