*免责声明:
1、视频来源于传智播客
2、此方法仅提供参考
本文代码根据B站《零基础入门六天学会QT完整版》中的P52和P53,其中视频有缺失,为了造福其他兄弟,在此补上缺失代码
首先需要创建两个类:ServerWidget和ClientWidget类
一、UI文件
1.serverwidget.ui
2.clientwidget.ui
二、.h文件
1.serverwidget.h
2.clientwidget.h
三、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
四、运行效果图
文章来源:https://www.toymoban.com/news/detail-424248.html
以上就是视频中TCP文件传输的代码,若有发现错误可以评论指出。文章来源地址https://www.toymoban.com/news/detail-424248.html
到了这里,关于QT中TCP文件传输的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!