UDP通信之窗口实现
程序员文章站
2022-06-30 19:58:53
...
UDP面向窗口通信的简单实现
介绍:UDP数据报文协议是面向无连接的传输层报文协议。UDP主要用在强调实时,主动推送的系统中,不存在“粘包”情况。
step1.新建界面工程,添加列表部件,用于显示和接收数据。
step2.在头文件中,添加包含QNetwordInterface,QHostAddress,QudpSocket模块,添加网络数据报文的结构定义,重载的timerEvent定义,添加接收数据报文操作定义,定义主机地址,定义发送和接收的socket与缓冲区。
//数据报文结构
#pragma pack(push) //保存对齐状态
#pragma pack(4) //设定为4字节对齐状态
struct DataStruct{
unsigned int index;
int hour;
int minute;
int second;
int msec;
};
//数据缓冲区
union NetBuffer{
DataStruct data;
char dataBuffer[20];
};
#pragma pack(pop) //恢复字节对齐状态
public:
//重载定时器触发执行操作
void timerEvent(QTimerEvent * event);
public slots:
//读取数据报文操作
void readPendingDatagrams();
private:
//定义主机地址
QHostAddress hostAddress;
//发送与接收socket
QUdpSocket udpSendSocket,udpRecvSocket;
//发送与接收缓冲区
NetBuffer sendBuffer,recvBuffer;
step3.在构造函数中获取本机地址,绑定发送和接收socket,设置响应接收socket接收信号的槽
//获取本机IP地址
QList<QHostAddress> addressList = QNetworkInterface::allAddresses();
hostAddress = addressList.at(0);
//网络端口绑定
udpSendSocket.bind(hostAddress,7000);
udpRecvSocket.bind(hostAddress,7001);
//设置定时器
this->startTimer(5000);
//初始化计数器
sendBuffer.data.index = 0;
//建立接收socket的连接
QObject::connect(&udpRecvSocket,SIGNAL(readyRead()),
this,SLOT(readPendingDatagrams()));
注意:readyRead()信号是在有进入的数据被读取时,此信号被发送,即接收socket一有数据报文包,槽函数即被调用进行数据读取和显示。
step4.实现发送与接收操作,并在界面上显示,数据发送为一秒发送一次。这里使用联合的方式解析网络数据结构。
//在timeEvent中设置发送数据并显示
void MainWindow::timerEvent(QTimerEvent *event)
{
QTime tm = QTime::currentTime();
sendBuffer.data.hour = tm.hour();
sendBuffer.data.minute = tm.minute();
sendBuffer.data.second = tm.second();
sendBuffer.data.msec = tm.msec();
udpSendSocket.writeDatagram(sendBuffer.dataBuffer,sizeof(sendBuffer),hostAddress,7001);
QString displayString;
displayString = QString("Index:%1\nTime=%2:%3:%4.%5\n")
.arg(sendBuffer.data.index)
.arg(sendBuffer.data.hour,2,10,QChar('0'))
.arg(sendBuffer.data.minute,2,10,QChar('0'))
.arg(sendBuffer.data.second,2,10,QChar('0'))
.arg(sendBuffer.data.msec,3,10,QChar('0'));
ui->listWidget->insertItem(0,displayString);
sendBuffer.data.index++;
}
//在槽中接收数据并显示
void MainWindow::readPendingDatagrams()
{
QHostAddress senderIP;
quint16 senderPort;
udpRecvSocket.readDatagram(recvBuffer.dataBuffer,sizeof(recvBuffer),&senderIP,&senderPort);
QString displayString;
displayString = QString("Index:%1\nTime=%2:%3:%4.%5\n")
.arg(recvBuffer.data.index)
.arg(recvBuffer.data.hour,2,10,QChar('0'))
.arg(recvBuffer.data.minute,2,10,QChar('0'))
.arg(recvBuffer.data.second,2,10,QChar('0'))
.arg(recvBuffer.data.msec,2,10,QChar('0'));
ui->listWidget_2->insertItem(0,displayString);
}
上一篇: 公司老是换技术好吗? JSF互联网框架
下一篇: Struts2.16中的一些问题