QT开发的即时通讯软件(基于UDP)

这是本人在学习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

 

  • 3
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值