基于UDP的QT群聊功能

写在前面

        udpSocket 是一个QUdpSocket类的对象,用于实现基于UDP协议的网络通信。它可以绑定到指定的IP地址和端口,以便接收和发送数据报。通过该对象,程序可以使用writeDatagram()函数将数据报文发送到指定的IP地址和端口,也可以使用readyRead()信号来接收数据报文。同时,它还提供了一些其他的函数和信号,如bind()、readDatagram()等,用于实现更加复杂的网络通信功能。

1、初始化部分

        绑定了一个端口,并连接了readyRead信号以接收数据报。还包括了一个getMsg函数,用于获取消息文本并清空输入框。最后,通过连接按钮的点击事件来调用sendMsg函数发送消息。

    this->port=9999; //随机
    this->udpSocket =new QUdpSocket(this);
    //绑定端口
    //ShareAddress和ReuseAddressHint模式表示可以与其他进程共享该地址,并且可以重用该地址
    this->udpSocket->bind(this->port,QUdpSocket::ShareAddress| QUdpSocket::ReuseAddressHint);
    connect(this->udpSocket, &QUdpSocket::readyRead, this, &MainWindow::receiveMsg);
    connect(ui->sendBtn, &QPushButton::clicked,this,[=](){
        sendMsg(msg);
    }  );

2、发送消息部分

        在发送消息时,它创建了一个QByteArray数组,并使用QDataStream将消息类型和用户名写入数组中。根据消息类型的不同,在流中写入相应的消息内容。如果消息类型是msg,并且消息文本为空,则会弹出警告对话框。最后,使用UDP协议将数组中的数据报文发送到指定的IP地址和端口。

QString MainWindow::getMsg()
{
    QString msg = ui->msgTextEdit->toPlainText();
    ui->msgTextEdit->clear();
    ui->msgTextEdit->setFocus();
    return msg;
}

void MainWindow::sendMsg(MainWindow::msgType type)
{
    //创建数组, 将数据转换为二进制格式
    QByteArray array;
    QDataStream stream(&array,QIODevice::WriteOnly); //创建流,将数据储存在数组中
    stream<<type<<this->m_patient->m_name; //流入类型和用户名
    switch (type)
    {
        case msg:
           if(ui->msgTextEdit->toPlainText()=="")
           {
                QMessageBox::warning(this,"警告","发送信息不能为空",QMessageBox::Ok);
                return;
           }
           //流入信息
           stream<<this->getMsg();
           break;
        case userEnter:
           break;
        case userLeft:
           break;
        default:
           break;
    }
    //书写报文
    //使用UDP协议将数组中的数据报文发送到指定的IP地址和端口
    this->udpSocket->writeDatagram(array,QHostAddress::Broadcast, this->port);//QHostAddress::Broadcast 表示广播地址,表示将数据发送到网络上的所有设备上
}

3、接受消息部分

        首先获取等待接收的数据报的大小,然后创建一个指定大小的QByteArray数组,并将数据报的内容读取到数组中。接着,使用QDataStream对数组进行解析,获取其中的消息类型、用户名和消息内容。根据消息类型的不同,进行相应的处理,例如在UI界面上显示消息。

void MainWindow::receiveMsg()
{
    //pendingDatagramSize() 函数是 QUdpSocket 类的成员函数,用于获取等待接收的数据报的大小
    qint64 size = this->udpSocket->pendingDatagramSize();
    int mysize = static_cast<int>(size); //转成int类型

    //使用字符数据的原因:在网络编程中,通常需要处理各种类型的数据,
    //包括二进制数据、文本数据、图像、音频等等。因此,使用字节数组可以更加灵活地处理不同类型的数据
    //创建了一个指定大小的字节数组,初始值全为0
    QByteArray array =QByteArray(mysize,0);

    //将数据报的内容读取到字节数组中
    this->udpSocket->readDatagram(array.data(),size);

    //使用 QDataStream 类型的对象对字节数组进行解析,获取其中的消息类型、用户名和消息内容
    QDataStream stream(&array,QIODevice::ReadOnly);
    int msgtype; //在网络编程中,通常会将消息类型、数据长度等信息转换为整数类型,并将其写入字节数组中进行传输。在接收端,再根据消息类型进行解析和处理
    stream>>msgtype;
    QString username,message;
    QString time=QDateTime::currentDateTime().toString("yyyy-MM-dd hh::mm::ss");
    switch (msgtype)
    {
        case msg:
           stream>>username>>message;//流出用户名和信息
           ui->messageBrowser->setTextColor(Qt::blue); //设置字体颜色
           ui->messageBrowser->setCurrentFont(QFont("Times New Roman",12)); //字体
           ui->messageBrowser->append("["+username+']'+time);
           ui->messageBrowser->append(message);
           break;
        case userEnter:
           stream>>username;
           //user_Enter(username);
           break;
        case userLeft:
           stream>>username;
           //user_Left(username,time);
           break;
        default:
           break;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值