这是本人在学习QT和计算机网络的时候自己开发的UDP网络通讯软件,可收可发,可作为服务端也可以作为客户端,并可以使用mysql数据库存储历史记录,亲测可用,注释详细,欢迎参考,先上图,源码附在下面,也可以直接在这下载:https://download.csdn.net/download/qq_18108083/10798364 赚点积分,我一点也没有,谢谢,嘿嘿~

(1).main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF8")); //保证正常显示中文
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF8"));
QApplication a(argc, argv);
MainWindow w;
w.show();
w.connectDatabase(); //连接数据库
return a.exec();
}
(2).mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// QPalette palette; //设置窗口颜色
// palette.setBrush(this->backgroundRole(), Qt::lightGray);
// this->setPalette(palette);
timer =new QTimer(this); //创建定时器
receiveCount=0; //接收区计数初始化
sendCount=0; //发送区计数
QObject::connect(ui->sendPushButton,SIGNAL(clicked(bool)),this,SLOT(sendUdpSlot())); //发送upd
QObject::connect(ui->clearReceivePushButton,SIGNAL(clicked(bool)),this,SLOT(clearReceiveSlot())); //清空接收区
QObject::connect(ui->autoSendCheckBox,SIGNAL(stateChanged(int)),this,SLOT(setAutoSendSlot())); //自动发送 开关定时器
QObject::connect(this->timer,SIGNAL(timeout()),this,SLOT(sendUdpSlot())); //自动发送延时溢出
QObject::connect(ui->delayTimeLineEdit,SIGNAL(returnPressed()),this,SLOT(setAutoSendSlot())); //定时line回车
QObject::connect(ui->saveLocalIpPushButton,SIGNAL(clicked(bool)),this,SLOT(saveNetworkSetSlot())); //保存设置
QObject::connect(ui->showHistoryPushButton,SIGNAL(clicked(bool)),this,SLOT(showUdpRecordSlot())); //显示历史消息记录
QObject::connect(ui->clearHistoryPushButton,SIGNAL(clicked(bool)),this,SLOT(clearDatabaseSlot())); //清除数据库
//对于接收来说只需要监听端口即可
//bind(10000,QAbstractSocket::DontShareAddress);bind(port);
//对于发送来说
/*
//udpSocket->writeDatagram(发送的数据,发送数据的长度,IP,端口); 返回一个长度.
len=udpSocket->writeDatagram(text.toLatin1(),text.length(),QHostAddress::LocalHost,port);
*/
uSocket=new QUdpSocket;
/*打印本地IP QHostAddress::LocalHost*/
ui->receiveContextTextEdit->append("******************************************************");
ui->receiveContextTextEdit->append(" 本地IP");
ui->receiveContextTextEdit->append("******************************************************");
QList<QHostAddress> list = QNetworkInterface::allAddresses();
foreach (QHostAddress address, list)
{
if(address.protocol() == QAbstractSocket::IPv4Protocol) //使用IPv4地址
ui->receiveContextTextEdit->append(address.toString());
}
ui->receiveContextTextEdit->append("******************************************************");
/*程序启动时初始化网络设置*/
QString listenip=ui->listenIpLineEdit->text(); //获取监听的本地ip
quint16 listenport=quint16(ui->listenPortLineEdit->text().toUInt()); //获取监听端口//后面要更改设置
uSocket->bind(QHostAddress(listenip),listenport); //绑定端口 ,绑定后一般不再更改
//uSocket->bind(QHostAddress("192.168.1.33"),quint16(63392)); //绑定端口 ,绑定后一般不再更改
connect(uSocket,SIGNAL(readyRead()),this,SLOT(receiveUdpSlot())); //在收到数据以后,SOCKET触发事件
}
MainWindow::~MainWindow()
{
delete ui;
delete uSocket; //清理内存
}
void MainWindow::receiveUdpSlot()
{
while(uSocket->hasPendingDatagrams()) //有挂起的数据
{
QByteArray receiveData; //因为传来的数据类型是未知的,用bytearray类型
receiveData.resize(uSocket->pendingDatagramSize()); //receiveData的数据大小取决于接收到的数据
uSocket->readDatagram(receiveData.data(),receiveData.size()); //读取数据
if(!ui->stopShowCheckBox->isChecked()) //停止刷新接收区未被选中
{
QDateTime currentTime=QDateTime::currentDateTime(); //获取当前时间
QString curTime=currentTime.toString("hh.mm.ss"); //将时间转换成字符串格式(按格式)
if(ui->showTimeCheckBox->isChecked()) //显示时间戳被选中
{
ui->receiveContextTextEdit->append("# "+curTime+":"); //追加文本框中的内容 append是从新的一行打印
}
ui->receiveContextTextEdit->append(QString::fromUtf8(receiveData)); //添加文本
ui->receiveContextTextEdit->scrollBarWidgets(Qt::AlignBottom); //滚轮自动移动到末端
receiveCount+=receiveData.count(); //更新接收计数值
ui->receiveCountLabel->setText(QVariant(receiveCount).toString());
MainWindow::insertDataToDb(curTime,QString::fromUtf8(receiveData)); //往数据库中插入
}
}
}
void MainWindow::sendUdpSlot() //发送Udp信号槽(发送按钮触发,时间溢出触发)
{
QString sendip=ui->ipLineEdit->text(); //获取目标ip
quint16 sendport=quint16(ui->portLineEdit->text().toUInt()); //获取目标端口
QString sendContext=ui->sendcontextTextEdit->document()->toPlainText();
uSocket->writeDatagram(sendContext.toUtf8(),QHostAddress(sendip),quint16(sendport)); //往 IP+prot上 发生数据
sendCount+=sendContext.count();//更新发送计数值
ui->sendCountLabel->setText(QVariant(sendCount).toString());
/*
//QUdpSocket qus; //定义一个UDP
QString myMessage = "I' UDP Server";
for(int i=0;i<100;i++) //发送100次
{
uSocket->writeDatagram(myMessage.toUtf8(),QHostAddress("192.168.37.129"),quint16(8000)); //往 IP+prot上 发生数据
std::cout<<"server send"<<std::endl;
}
*/
}
void MainWindow::clearReceiveSlot() //清空接收区
{
ui->receiveContextTextEdit->clear();
receiveCount=0; //更新接收计数值
ui->receiveCountLabel->setText(QVariant(receiveCount).toString());
}
void MainWindow::setAutoSendSlot() //设置自动发送(刚被勾选时触发,时间line回车)
{
this->timer->stop(); //首先关闭定时器
if(ui->autoSendCheckBox->isChecked()) //如果自动发送被选中
{
if((!ui->delayTimeLineEdit->text().isEmpty())&&ui->delayTimeLineEdit->text().toLong()!=0) //如果时间间隔非空且自动转整数后不为0
{
this->timer->start(ui->delayTimeLineEdit->text().toLong()); //开启定时器 单位毫秒
}
else // 发送区空
{
ui->autoSendCheckBox->setCheckState(Qt::Unchecked); //强行设置未被勾选
QMessageBox::information(this,"提示:","未成功设置时间间隔");
return;
}
}
else
{
this->timer->stop();
}
}
void MainWindow::saveNetworkSetSlot() // 保存设置
{
QMessageBox::information(this,"提示:","尚未开发");
}
void MainWindow::connectDatabase() //成员函数:连接数据库
{
db=QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("udpdatabase");
db.setUserName("root");
db.setPassword("020513");
bool ok = db.open();
if(ok)
{
qDebug()<<"open success"; //连接数据库成功
QMessageBox::information(this,"提示","成功连接数据库");
ui->databaseStatusLabel->setText("已连接");
QPalette palette; //设置字体颜色
palette.setColor(QPalette::WindowText,Qt::green);
ui->databaseStatusLabel->setPalette(palette);
}
else
{
qDebug()<<"open error"<<this->db.lastError().text();
QMessageBox::information(this,"连接失败",this->db.lastError().text());
ui->databaseStatusLabel->setText("未连接");
QPalette palette; //设置字体颜色
palette.setColor(QPalette::WindowText,Qt::red);
ui->databaseStatusLabel->setPalette(palette);
}
}
void MainWindow::showUdpRecordSlot() //显示消息记录QString time,QString udpMessage
{
if(this->db.isOpen())
{
QSqlQuery query;
query.exec("select * from message;");
while (query.next())
{
QString time = query.value(0).toString();
QString message= query.value(1).toString();
ui->receiveContextTextEdit->append(time+" "+message);
}
}
}
void MainWindow::insertDataToDb(QString time,QString message) //往数据库中插入数据
{
//加上连接数据库状态判断
if(this->db.isOpen())
{
QSqlQuery query;
query.prepare("INSERT INTO message (time, udpmessage) "
"VALUES (:time, :udpmessage)");
query.bindValue(":time", time);
query.bindValue(":udpmessage", message);
query.exec();
qDebug()<<"成功插入数据";
}
}
void MainWindow::clearDatabaseSlot() //清空数据库记录
{
if(this->db.isOpen())
{
QSqlQuery query;
query.exec("truncate table message");
QMessageBox::information(this,"提示","成功清除历史记录");
}
}
(3).mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QUdpSocket>
#include <QTextCodec>//保证正常显示中文
#include <QHostAddress>
#include <QHostInfo>
#include <QNetworkInterface>
#include <iostream> //std ::cout
#include <QByteArray>
#include <QCoreApplication>
#include <QDateTime>
#include <Qpalette>
#include <QTimer> //定时器
#include <QMessageBox>
#include <QtSql> //sql数据库
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void connectDatabase(); //连接数据库
void insertDataToDb(QString,QString); //往数据库中插入数据
private:
Ui::MainWindow *ui;
quint64 receiveCount; //接收区计数
quint64 sendCount; //发送区计数
QTimer *timer; //定义定时器指针
QUdpSocket *uSocket; //因为要在槽函数中使用,因此在这里定义
QSqlDatabase db; //定义一个全局的数据库
private slots:
void receiveUdpSlot(); //槽函数用于对接受的数据进行处理
void sendUdpSlot(); //发送Udp信号槽(发送按钮触发)
void clearReceiveSlot(); //清空接收区
void saveNetworkSetSlot(); //保存网络设置
void setAutoSendSlot(); //设置自动发送,打开定时器(刚被勾选时触发,时间line回车)
void showUdpRecordSlot(); //显示消息记录
void clearDatabaseSlot(); //清空数据库记录
};
#endif // MAINWINDOW_H