[QT network programming] realize UDP protocol communication

Summary: This issue mainly explains the realization of UDP protocol communication in QT.

1. UDP protocol communication

The Internet protocol suite supports a connectionless transport protocol called User Datagram Protocol (UDP, User Datagram Protocol). UDP provides applications withA method of sending encapsulated IP packets without establishing a connection. RFC 768 describes UDP.
insert image description here
The UDP protocol can be divided into: Unicast, Multicast and Broadcast according to the message transmission mode.

  1. Unicast : A datagram sent by a UDP client is only sent to another UDP client with a specified address and port.is a one-to-one data transfer
  2. Multicast : also known as multicast, the UDP client joins a multicast group specified by another multicast IP address,All members in the group can receive the datagram sent by the member to the multicast address, similar to the QQ group function.
  3. Broadcast : A datagram sent by a UDP client,All other UDP clients within the same network range can receive

Two, the processing of UDP protocol in Qt

Qt provides the QUdpSocket class for creating UDP sockets.

1.QUdpSocket

The QUdpSocket class inherits from QAbstractSocket and provides the creation of UdpSocket sockets, connection to alignment servers, and group addition.
insert image description here

3. Qt implements UDP communication

UDP communication is information transfer between peer servers. In fact, there is no need to specify the client and server, but for the sake of easy understanding, I still use the CS structure when implementing it.
The implementation steps are as follows:
创建UDP套接字 --> 绑定端口 --> 加组(区分消息传送模式) -->发送数据(区分消息传送模式) --> 接受数据

1. Client

The client implements sending data.

#ifndef UDPCLIENT_H
#define UDPCLIENT_H

#include <QObject>
#include <QHostAddress>
#include <QUdpSocket>
#include <QDebug>
#include <QTimer>

class UDPClient :QObject
{
    
    
    Q_OBJECT
public:
    UDPClient();

    void InitSocket();//初始化UDP套接字

    void InitTimer();//初始化定时器

public slots:
    void SendData();//发送数据

private:
    QUdpSocket *mUdpSocket;//UDP套接字对象
    QHostAddress mGroupAddress;//组播地址
    QTimer *mTimer;//定时器对象
    int mType;//记录UDP消息传送模式 0:单播 1:广播 2:组播(多播)
};

#endif // UDPCLIENT_H
#include "udpclient.h"

UDPClient::UDPClient()
{
    
    
//    mType = 0;//Unicast
//    mType = 1;//Broadcast
    mType = 2;//Multicast
    InitSocket();
    InitTimer();

}

void UDPClient::InitSocket()
{
    
    
    mUdpSocket = new QUdpSocket;//初始化socket
    mGroupAddress.setAddress("239.2.2.222");//设置组播地址
    mUdpSocket->bind(6666);//绑定端口号
    if(mType == 2)
    {
    
    
        //组播的数据的生存期,数据报没跨1个路由就会减1.表示多播数据报只能在同一路由下的局域网内传播
        mUdpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption,1);
    }
}

void UDPClient::InitTimer()
{
    
    
    mTimer = new QTimer;//初始化定时器
    connect(mTimer,&QTimer::timeout,this,[=]
    {
    
    
        SendData();
    });
    mTimer->start(1000);//每隔一秒发送一次数据
}

void UDPClient::SendData()
{
    
    
    QByteArray _data = "hello";
    if(mType == 0)//单播
    {
    
    
        QHostAddress _peerHostAddress = QHostAddress("10.0.0.177");//对位服务器IP
        quint16 _port = 6666;//对位服务器端口
        if(-1 !=mUdpSocket->writeDatagram(_data.data(),_data.size(),_peerHostAddress,_port))
        {
    
    
            qDebug()<< "Unicast ==> Send data : "<< _data<<endl;
        }
        mUdpSocket->flush();
    }
    else if(mType == 1)//广播
    {
    
    
        quint16 _port = 6666;//广播端口
        if(-1 !=mUdpSocket->writeDatagram(_data.data(),QHostAddress::Broadcast,_port))
        {
    
    
            qDebug()<< "Broadcast ==> Send data : "<< _data<<endl;
        }
        mUdpSocket->flush();
    }
    else if(mType == 2)//组播
    {
    
    
        quint16 _port = 8888;//组播端口
        if(-1 != mUdpSocket->writeDatagram(_data.data(),mGroupAddress,_port))
        {
    
    
            qDebug()<< "Multicast ==> Send data : "<< _data<<endl;
        }
        mUdpSocket->flush();
    }
    else
    {
    
    
        qDebug()<< "mType is error! "<<endl;
        return;
    }


}

2. Server side

The server side implements data reception.

#ifndef UDPSERVER_H
#define UDPSERVER_H

#include <QObject>
#include <QHostAddress>
#include <QUdpSocket>
#include <QDebug>

class UDPServer : QObject
{
    
    
    Q_OBJECT
public:
    UDPServer();
    void InitSocket();//初始化套接字

public slots:
    void ReadPendingDataframs();//读取消息

private:
    QUdpSocket *mUdpSocket;//UDP套接字
    QHostAddress mGroupAdress;//组播地址
    int mType; //记录UDP消息传送模式 0:单播 1:广播  2:组播(多播)
};

#endif // UDPSERVER_H
#include "udpserver.h"
UDPServer::UDPServer()
{
    
    
//    mType = 0;//Unicast
//    mType = 1;//Broadcast
    mType = 2;//Multicast
    InitSocket();

}

void UDPServer::InitSocket()
{
    
    
    //初始化socket,设置组播地址
    mUdpSocket = new QUdpSocket;
    mGroupAdress.setAddress("239.2.2.222");
    if(mType == 0 || mType == 1)
    {
    
    
        //绑定本地IP和端口号
        mUdpSocket->bind(6666);
    }
    else if(mType == 2)
    {
    
    
        if(mUdpSocket->bind(QHostAddress::AnyIPv4,8888,QUdpSocket::ShareAddress))
        {
    
    
            //加入组播地址
            mUdpSocket->joinMulticastGroup(mGroupAdress);
            qDebug()<<("Join Multicast Adrress [")<<mGroupAdress.toString()
                   <<("] Successful!")<<endl;
        }
    }
    else
    {
    
    
        qDebug()<< "mType is error! "<<endl;
        return;
    }

    connect(mUdpSocket,&QUdpSocket::readyRead,this,[=]{
    
    
        ReadPendingDataframs();
    });
}



void UDPServer::ReadPendingDataframs()
{
    
    
    QByteArray _data;
    _data.resize(mUdpSocket->pendingDatagramSize());
    if(mType == 0)//Unicast
    {
    
    
        QHostAddress *_peerHostAddress = new QHostAddress("10.0.0.32");
        quint16 _port = 6666;
        while(mUdpSocket->hasPendingDatagrams())
        {
    
    
            mUdpSocket->readDatagram(_data.data(),_data.size(),_peerHostAddress,&_port);//接收指定IP和端口的udp报文
            qDebug()<<"Unicast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
        }
    }
    else if(mType == 1)//Broadcast
    {
    
    
        QHostAddress _peerHostAddress;
        quint16 _port;
        while(mUdpSocket->hasPendingDatagrams())
        {
    
    
            mUdpSocket->readDatagram(_data.data(),_data.size(),&_peerHostAddress,&_port);//接收同一子网的udp报文
            qDebug()<<"Broadcast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
        }
    }
    else if(mType == 2)//Multicast
    {
    
    
        QHostAddress _peerHostAddress;
        quint16 _port;
        while(mUdpSocket->hasPendingDatagrams())
        {
    
    
            mUdpSocket->readDatagram(_data.data(),_data.size(),&_peerHostAddress,&_port);//接收同组的udp报文
            qDebug()<<"Multicast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
        }
    }
    else
    {
    
    
        qDebug()<< "mType is error! "<<endl;
        return;
    }
}

end

The above is the whole content of QT to realize UDP protocol communication, remember to add the network module:)

Guess you like

Origin blog.csdn.net/wddkxg/article/details/129458220