UDP通信之窗口实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013776188/article/details/76231986

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);

}


step5.在*.pro文件中添加QT += core gui network





猜你喜欢

转载自blog.csdn.net/u013776188/article/details/76231986