#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setWindowTitle("客户端程序");
////初始化客户端
IniClient();
}
MainWindow::~MainWindow()
{
delete ui;
}
////////////////////////////////////////////////////////////////////////////
///初始化客户端
void MainWindow::IniClient()
{
// loadSize = 4*1024;
// totalBytes = 0;
// bytesWrittenSize = 0;
// bytesToWrite = 0;
this->ClearSendInfo();///初始化信息
tcpClient = new QTcpSocket(this);
//当连接服务器成功时,发出connected()信号
connect(tcpClient,SIGNAL(connected()),this,SLOT(slot_connected()));
///发送数据、文件
connect(tcpClient,SIGNAL(bytesWritten(qint64)),this,
SLOT(updateClientProgress(qint64)));
///数据读取、文件
connect(tcpClient,SIGNAL(readyRead()),this,
SLOT(ReadServerData()));
connect(tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),this,
SLOT(displayError(QAbstractSocket::SocketError)));
//开始使”发送“按钮不可用
// ui->sendButton->setEnabled(false);
}
///*************************************************文件发送 Begin********************************////
///
///文件相关信息初始化
void MainWindow::ClearSendInfo()
{
totalBytes = 0;
bytesWrittenSize = 0;
bytesToWrite = 0;
ui->clientProgressBar->reset();
}
///文件属性信息发送
void MainWindow::startTransfer()
{
QByteArray FileInf_outBlock;
localFile = new QFile(fileName);
if(!localFile->open(QFile::ReadOnly))
{
qDebug() << "open file error!";
return;
}
totalBytes = localFile->size();
//文件总大小
QDataStream sendOut(&FileInf_outBlock,QIODevice::WriteOnly);
sendOut.setVersion(QDataStream::Qt_4_8);
QString currentFileName = fileName.right(fileName.size() - fileName.lastIndexOf('/')-1);
sendOut << qint64(0) << qint64(0) << currentFileName;
//依次写入总大小信息空间,文件名大小信息空间,文件名
totalBytes += FileInf_outBlock.size();
//这里的总大小是文件名大小等信息和实际文件大小的总和
sendOut.device()->seek(0);
sendOut<<totalBytes<<qint64((FileInf_outBlock.size() - sizeof(qint64)*2));
//返回outBolock的开始,用实际的大小信息代替两个qint64(0)空间
bytesToWrite = totalBytes - tcpClient->write(FileInf_outBlock);
FileInf_outBlock.resize(0);
//发送完头数据后剩余数据的大小
ui->clientStatusLabel->setText(tr("已连接"));
}
///文件按照字节大小发送
void MainWindow::FileDataProgress(qint64 numBytes)
{
bytesWrittenSize += (int)numBytes;
QByteArray PerDataoutBlock;
//已经发送数据的大小
if(bytesToWrite > 0) //剩余的数据
{
PerDataoutBlock = localFile->read(qMin(bytesToWrite,qint64(SENDFILESIZE)));
//每次发送loadSize大小的数据,这里设置为4KB,如果剩余的数据不足4KB,
//就发送剩余数据的大小
bytesToWrite -= (int)tcpClient->write(PerDataoutBlock);
//发送完一次数据后还剩余数据的大小
PerDataoutBlock.resize(0);
//清空发送缓冲区
}
else
{
localFile->close(); //如果没有发送任何数据,则关闭文件
}
//更新进度条
if(bytesWrittenSize == totalBytes) //发送完毕
{
ui->clientStatusLabel->setText(tr("传送文件 %1 成功").arg(fileName));
localFile->close();
}
this->UpdaProgressBar(bytesWrittenSize,totalBytes);
}
///*************************************************文件发送 End********************************////
///*************************************************文件接收 Begin********************************////
///
void MainWindow::ClearReceiveFileInfo()
{
ReceivetotalBytes = 0;
bytesReceived = 0;
ReceivefileNameSize = 0;
}
///接收数据文件操作
void MainWindow::ReceiveFile()
{
QDataStream in(tcpClient);
in.setVersion(QDataStream::Qt_4_8);
if(bytesReceived <= sizeof(qint64)*2)
{
//如果接收到的数据小于16个字节,那么是刚开始接收数据,我们保存到//来的头文件信息
if((tcpClient->bytesAvailable() >= sizeof(qint64)*2)
&& (ReceivefileNameSize == 0))
{
in >> ReceivetotalBytes >> ReceivefileNameSize; ///总大小、文件名大小
bytesReceived += sizeof(qint64) * 2;
}
if((tcpClient->bytesAvailable() >= ReceivefileNameSize)
&& (ReceivefileNameSize != 0))
{
//接收文件名,并建立文件
in >> ReceivefileName; ///文件名称
ui->clientStatusLabel->setText(tr("接收文件 %1 …").arg(ReceivefileName));
bytesReceived += ReceivefileNameSize;
ReceivelocalFile = new QFile(ReceivefileName);
if(!ReceivelocalFile->open(QFile::WriteOnly))
{
qDebug() << "open file error!";
return;
}
}
else return;
}
if(bytesReceived < ReceivetotalBytes)
{ //如果接收的数据小于总数据,那么写入文件
bytesReceived += tcpClient->bytesAvailable();
QByteArray inBlock; //数据缓冲区
inBlock = tcpClient->readAll();
ReceivelocalFile->write(inBlock);
inBlock.resize(0);
}
if(bytesReceived == ReceivetotalBytes)
{ //接收数据完成时
ReceivelocalFile->close();
ui->clientStatusLabel->setText(tr("接收文件 %1 成功!")
.arg(ReceivefileName));
}
//更新进度条
UpdaProgressBar(bytesReceived,ReceivetotalBytes);
}
///*************************************************文件接收 End********************************////
///更新进度条
void MainWindow::UpdaProgressBar(qint64 bytesWrittenSize,qint64 totalBytes)
{
///更新进度条
ui->clientProgressBar->setMaximum(totalBytes);
ui->clientProgressBar->setValue(bytesWrittenSize);
}
///与服务器建立连接
void MainWindow::slot_connected()
{
MyMessageBox::ChMessageOnlyOk("连接服务器成功!");
}
//更新进度条,实现文件的传送
void MainWindow::updateClientProgress(qint64 numBytes)
{
switch (m_datatype) {
case SENDData:
qDebug()<<"qint64 numBytes"<<numBytes;
break;
case SENDFILE:
FileDataProgress(numBytes);
break;
default:
MyMessageBox::ChMessageOnlyOk("数据内容有误传输失败");
break;
}
}
/////显示错误
void MainWindow::displayError(QAbstractSocket::SocketError) //显示错误
{
qDebug() << tcpClient->errorString();
tcpClient->close();
ui->clientProgressBar->reset();
ui->clientStatusLabel->setText(tr("客户端连接失败"));
// ui->sendButton->setEnabled(true);
this->ClearSendInfo();///初始化信息
}
///建立连接
void MainWindow::on_pushButton_Connect_clicked()
{
this->ClearSendInfo();///初始化信息
ui->clientStatusLabel->setText(tr("连接中…"));
tcpClient->connectToHost(ui->hostLineEdit->text(),
ui->portLineEdit->text().toInt());//连接
}
///发送文件
void MainWindow::on_sendButton_clicked()
{
// send();
m_datatype = SENDFILE;
fileName = FileHelper::GetFileName("*");
if(!fileName.isEmpty())
{
startTransfer();
ui->clientStatusLabel->setText(tr("打开文件 %1 成功!")
.arg(fileName)
Qt写的TCP的Server和Client程序,支持文件和数据内容的交互
2星 需积分: 33 95 浏览量
2016-01-20
22:04:07
上传
评论
收藏 25KB ZIP 举报
weima007
- 粉丝: 89
- 资源: 53
最新资源
- Sora AI-关于文生视频的使用场景说明
- suno AI文生视频的相关教程和介绍使用
- 什么是后端开发-关于后端开发的一些小介绍分享
- Jurassic Pack Vol. II Dinosaurs 侏罗纪包卷恐龙二号Unity游戏模型资源unitypackage
- Jurassic Pack Vol. III Dinosaurs 侏罗纪包卷恐龙三号Unity游戏模型资源unitypackag
- Ultimate Seating Controller 终极座椅控制器Unity游戏开发插件资源unitypackage
- 什么是人工智能-关于人工智能的相关介绍说明
- Figma Converter for Unity适用Unity的Figma转换器Unity游戏开发插件unitypackage
- Creepy Animatronic Anims 令人毛骨悚然的电子动画Unity游戏动画插件资源unitypackage
- Rankings & Leaderboards 排名和排行榜Unity游戏开发插件资源unitypackage
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈