写在前面
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;
}
}