QT Tcp传输文件服务器

#pragma once

#include <QtWidgets/QWidget>
#include "ui_QtServer.h"
#include <QTcpServer>
#include <QTcpSocket>
#include <QFile>
#include <QTimer>

class QtServer : public QWidget
{
	Q_OBJECT

public:
	QtServer(QWidget *parent = Q_NULLPTR);

	void sendData();

private slots:
	void slotFile();	//选择文件
	void slotSend();	//发送文件

private:
	Ui::QtServerClass ui;

	QTcpServer *ptcpServer;		//监听套接字
	QTcpSocket *ptcpSocket;		//通讯套接字
	QFile file;					//文件对象
	QString fileName;			//文件名
	qint64 fileSize;			//文件大小
	qint64 sendSize;			//已发送大小
	QTimer timer;				//定时器
};
#include "QtServer.h"
#include <QFileDialog>
#include <QFileInfo>

QtServer::QtServer(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);

	//监听套接字
	ptcpServer = new QTcpServer(this);
	//监听
	ptcpServer->listen(QHostAddress::Any, 8888);
	setWindowTitle(QString::fromLocal8Bit("服务器端口:8888"));

	//将button 置灰
	ui.button_File->setEnabled(false);
	ui.button_Send->setEnabled(false);

	//如果客户端成功和服务器连接
	//监听套接字会自动触发 newConnection() 信号
	connect(ptcpServer, &QTcpServer::newConnection, [=]() {
		//取出套接字
		ptcpSocket = ptcpServer->nextPendingConnection();
		//获取对方的IP和端口
		QString IP = ptcpSocket->peerAddress().toString();
		quint16 port = ptcpSocket->peerPort();

		QString str = QString::fromLocal8Bit("[%1:%2]成功连接").arg(IP).arg(port);
		ui.textEdit->setText(str);

		//成功连接后,才能选择文件
		ui.button_File->setEnabled(true);
	});

	connect(ui.button_File, &QPushButton::clicked, this, &QtServer::slotFile);
	connect(ui.button_Send, &QPushButton::clicked, this, &QtServer::slotSend);

	connect(&timer, &QTimer::timeout, [=]() {
		//首先关闭定时器
		timer.stop();
		sendData();		//才开始发送文件
	});
}
void QtServer::slotFile()
{
	QString filePath = QFileDialog::getOpenFileName(this,QString::fromLocal8Bit("选择文件"),"../");
	if (!filePath.isEmpty())
	{
		fileName.clear();
		fileSize = 0;

		QFileInfo fileInfo(filePath);
		fileName = fileInfo.fileName();
		fileSize = fileInfo.size();

		sendSize = 0;

		file.setFileName(filePath);
		bool isOk = file.open(QIODevice::ReadOnly);
		if (isOk)
		{
			ui.textEdit->append(filePath);
			ui.button_File->setEnabled(false);
			ui.button_Send->setEnabled(true);
		}
	}
}
void QtServer::slotSend()
{
	//先发送文件头信息,后发送真正的文件
	QString head = QString::fromLocal8Bit("%1##%2").arg(fileName).arg(fileSize);

	qint64 len = ptcpSocket->write(head.toUtf8());
	if (len > 0)
	{
		//发送真正的文件信息  防止 TCP 粘包问题 需要开启一个定时器
		timer.start(20);	//开启定时器
	}
}
void QtServer::sendData()
{
	qint64 len = 0;
	do {
		//每次发送数据的大小
		char buf[1024] = { 0 };
		len = 0;

		//从文件读数据
		len = file.read(buf, sizeof(buf));
		//发送数据,读多少,发多少
		len = ptcpSocket->write(buf,len);

		//将已发送的数据累计
		sendSize += len;
	
	} while (len >0);

	//是否发送文件完毕
	if (sendSize == fileSize)
	{
		ui.textEdit->append(QString::fromLocal8Bit("文件发送完毕"));
		file.close();

		ptcpSocket->disconnectFromHost();		//发送完毕,断开连接
		ptcpSocket->close();
	}
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值