這是本人在學習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