源代码·Qt/C++使用小记9
立即下载
资源介绍:
Qt/C++使用小记9【使用UDP创建连接发送消息/传输单个文件】
#include "Widget.h"
#include "ui_Widget.h"
#include
#include
#include
#include
#include
#include
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget),
m_udpSocket(nullptr),
m_strFilePath(""),
m_bRecevieFile(false),
m_uFileStatus(Default_Status),
m_strReceviePath("")
{
ui->setupUi(this);
// 实例化对象
m_udpSocket = new MyCustomUdpSocket;
// 绑定接受数据的信号与槽
connect(m_udpSocket, &MyCustomUdpSocket::SignalRecevieData,
this, &Widget::SlotRecevieShowData);
// 初始化连接状态未连接为红色 连接上了则为绿色 通过心跳判定
// 心跳规定为3秒一次 若四秒内没有收到心跳 置为未连接
ui->label_status->setStyleSheet("color:red;");
// 绑定timer
connect(&m_timer, &QTimer::timeout, this, [=]{
ui->label_status->setStyleSheet("color:red;");
ui->label_status->setText(u8"未连接");
});
}
Widget::~Widget()
{
// 释放
DELETE_OBJ(m_udpSocket);
delete ui;
}
/**
* @brief on_pushButton_bind_clicked 绑定按钮点击槽函数
*/
void Widget::on_pushButton_bind_clicked()
{
// 判断是否绑定,若已绑定不能重复绑定
if(u8"断开绑定" == ui->pushButton_bind->text())
{
// 断开绑定
m_udpSocket->BreakBind();
qDebug()<<__FUNCTION__<GetConnectStatus();
// 设置ui
ui->pushButton_bind->setText(u8"绑定");
ui->pushButton_bind->setStyleSheet("color:black;");
}
else
{
//先进行绑定并获取返回值
bool flag = m_udpSocket->SetHostUdpInfo(ui->lineEdit_host_Addr->text(), ui->lineEdit_host_port->text().toInt());
//判断返回值是否绑定成功(为修改按钮文本和发送IP和端口号)
if(!flag)
{
//未绑定成功则在浏览框中提示然后返回
ui->textBrowser->append(u8"未绑定成功,请确认IP或端口号是否正确!" + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
return;
}
else
{
ui->textBrowser->append(u8"绑定成功!" + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
}
// 打印当前绑定信息
qDebug()<<__FUNCTION__<GetConnectStatus();
//更改按钮文本
ui->pushButton_bind->setText(u8"断开绑定");
ui->pushButton_bind->setStyleSheet("color:red;");
//发送IP和端口号信息
m_udpSocket->SetTargetUdpInfo(ui->lineEdit_target_addr->text(), ui->lineEdit_target_prot->text().toUShort());
}
}
/**
* @brief Widget::on_pushButton_send_message_clicked 发送消息按钮槽函数
*/
void Widget::on_pushButton_send_message_clicked()
{
// 如果为未绑定状态
if(m_udpSocket->GetConnectStatus() == QAbstractSocket::UnconnectedState)
{
ui->textBrowser->append(u8"网络未连接 " + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
}
else if(m_udpSocket->GetConnectStatus() == QAbstractSocket::BoundState) // 为绑定状态
{
// 获取界面输入的信息
QString strData = ui->textEdit->toPlainText();
if(strData.isEmpty())
return;
ui->textBrowser->append(u8"我 " + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
ui->textBrowser->append(" " + strData);
// 调用接口发送数据 统一编码格式为utf8发送
m_udpSocket->SendData(strData.toUtf8());
}
else
{
// 若为其他状态 则打印连接状态
qDebug()<<__FUNCTION__<GetConnectStatus();
}
}
/**
* @brief SlotRecevieShowData 接收数据并显示槽函数
* @param strData 具体内容
*/
void Widget::SlotRecevieShowData(const QByteArray &strData)
{
// 如果信息内容为宏定义的标识符 为开始传输文件 "START_SENDFILE"
if(QString::fromUtf8(strData) == START_SEND_FILE)
{
// 接收文件置true
m_bRecevieFile = true;
// 接收状态改为处理文件名字
m_uFileStatus = Handle_FileName_Status;
return;
}
// 如果信息内容为宏定义的标识符 为结束传输文件 "END_SENDFILE"
if(QString::fromUtf8(strData) == END_SEND_FILE)
{
// 重置接受文件状态
// 正在接收文件置否
m_bRecevieFile = false;
// 文件处理步骤置为初始状态
m_uFileStatus = Default_Status;
// 显示接收文件完成信息
QStringList strList = m_strReceviePath.split("/");
ui->textBrowser->append(u8"接收文件: " + strList.last() + u8" 完成 " + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
// 接收文件路径置空
m_strReceviePath = "";
return;
}
// 判断文件处理状态
switch(m_uFileStatus)
{
case Handle_FileName_Status:
{
// 文件放在根目录的RecevieFile文件夹下
QDir dir;
if(!dir.exists("./RecevieFile"))
{
bool b = dir.mkpath("./RecevieFile");
if(!b)
qDebug() << "Failed to create folder:" << "./RecevieFile";
}
const QString strFilePath = "./RecevieFile/" + QString::fromUtf8(strData);
ui->textBrowser->append(u8"开始接收文件: " + QString::fromUtf8(strData) + " " + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
// 保存文件的路径和文件名
m_strReceviePath = strFilePath;
// 改变接收文件状态为处理文件数据
m_uFileStatus = Handle_FileData_Status;
return;
}
case Handle_FileData_Status:
{
// 创建QFile
QFile file(m_strReceviePath);
// 用只写和追加写入
if (!file.open(QIODevice::WriteOnly | QIODevice::Append))
{
// 若创建或者打开失败 显示失败信息并置为初始状态
qDebug() << "Failed to create file" << m_strReceviePath;
m_uFileStatus = Default_Status;
m_bRecevieFile = false;
ui->textBrowser->append(u8"接收文件: " + m_strReceviePath + u8" 失败 " + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
m_strReceviePath = "";
return;
}
// 写入文件
file.write(strData.data(), strData.size());
file.close();
}
default:
break;
} // 判断文件处理状态
// 若不为接收文件状态 则正常接收消息
if(m_bRecevieFile == false)
{
// 如果信息不为空
if(!strData.isEmpty())
{
// 过滤掉心跳信息
if(QString::fromUtf8(strData) != HEARTBEAT_INFO)
{
ui->textBrowser->append(u8"对方 " + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
ui->textBrowser->append(" " + QString::fromUtf8(strData));
}
else // 处理心跳信息
{
// 收到心跳就暂停计时
m_timer.stop();
// 开启新一轮计时4秒间隔
m_timer.start(JUDGMENT_BREAK_LINK_SPACE);
ui->label_status->setText(u8"已连接");
ui->label_status->setStyleSheet("color:green;");
}
}
}
}
/**
* @brief on_pushButton_choose_file_clicked 选择文件按钮槽函数
*/
void Widget::on_pushButton_choose_file_clicked()
{
// 获取打开窗口的文件的路径
QS
资源文件列表:
TestProject.zip 大约有113个文件