概要:本期主要講解QT中對(duì)UDP協(xié)議通信的實(shí)現(xiàn)。
一、UDP協(xié)議通信
Internet 協(xié)議集支持一個(gè)無(wú)連接的傳輸協(xié)議,該協(xié)議稱(chēng)為用戶數(shù)據(jù)報(bào)協(xié)議(UDP,User Datagram Protocol)。UDP 為應(yīng)用程序提供了一種無(wú)需建立連接就可以發(fā)送封裝的 IP 數(shù)據(jù)包的方法。RFC 768 描述了 UDP。
UDP協(xié)議根據(jù)消息傳送模式可以分為:單播(Unicast)、組播(Multicast)和廣播(Broadcast)。
- 單播:一個(gè)UDP客戶端發(fā)出的數(shù)據(jù)報(bào)只發(fā)送到另一個(gè)指定地址和端口的UDP客戶端,是一對(duì)一的數(shù)據(jù)傳輸。
- 組播:也稱(chēng)多播,UDP客戶端加入到另一個(gè)組播IP地址指定的多播組,成員向組播地址發(fā)送的數(shù)據(jù)報(bào)組內(nèi)成員都可以接收到,類(lèi)似于QQ群功能。
- 廣播:一個(gè)UDP客戶端發(fā)出的數(shù)據(jù)報(bào),在同一網(wǎng)絡(luò)范圍內(nèi)其他所有的UDP客戶端都可以收到。
二、Qt中UDP協(xié)議的處理
Qt中提供了QUdpSocket類(lèi)用于創(chuàng)建UDP套接字。
1.QUdpSocket
QUdpSocket類(lèi)繼承于QAbstractSocket,提供了UdpSocket套接字的創(chuàng)建、連接對(duì)位服務(wù)器、加組等。
三、Qt實(shí)現(xiàn)UDP通信
UDP通信是對(duì)等服務(wù)器間信息傳遞,其實(shí)不需要指定客戶端和服務(wù)器端,但是為了便于理解,我在實(shí)現(xiàn)時(shí)仍然采用C-S的結(jié)構(gòu)。
實(shí)現(xiàn)步驟如下:創(chuàng)建UDP套接字 --> 綁定端口 --> 加組(區(qū)分消息傳送模式) -->發(fā)送數(shù)據(jù)(區(qū)分消息傳送模式) --> 接受數(shù)據(jù)
1.客戶端
客戶端實(shí)現(xiàn)發(fā)送數(shù)據(jù)。
#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();//初始化定時(shí)器
public slots:
void SendData();//發(fā)送數(shù)據(jù)
private:
QUdpSocket *mUdpSocket;//UDP套接字對(duì)象
QHostAddress mGroupAddress;//組播地址
QTimer *mTimer;//定時(shí)器對(duì)象
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");//設(shè)置組播地址
mUdpSocket->bind(6666);//綁定端口號(hào)
if(mType == 2)
{
//組播的數(shù)據(jù)的生存期,數(shù)據(jù)報(bào)沒(méi)跨1個(gè)路由就會(huì)減1.表示多播數(shù)據(jù)報(bào)只能在同一路由下的局域網(wǎng)內(nèi)傳播
mUdpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption,1);
}
}
void UDPClient::InitTimer()
{
mTimer = new QTimer;//初始化定時(shí)器
connect(mTimer,&QTimer::timeout,this,[=]
{
SendData();
});
mTimer->start(1000);//每隔一秒發(fā)送一次數(shù)據(jù)
}
void UDPClient::SendData()
{
QByteArray _data = "hello";
if(mType == 0)//單播
{
QHostAddress _peerHostAddress = QHostAddress("10.0.0.177");//對(duì)位服務(wù)器IP
quint16 _port = 6666;//對(duì)位服務(wù)器端口
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.服務(wù)器端
服務(wù)器端實(shí)現(xiàn)數(shù)據(jù)的接收。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-433502.html
#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,設(shè)置組播地址
mUdpSocket = new QUdpSocket;
mGroupAdress.setAddress("239.2.2.222");
if(mType == 0 || mType == 1)
{
//綁定本地IP和端口號(hào)
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報(bào)文
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);//接收同一子網(wǎng)的udp報(bào)文
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報(bào)文
qDebug()<<"Multicast ==> Receive data : "<<QString::fromLatin1(_data)<<endl;
}
}
else
{
qDebug()<< "mType is error! "<<endl;
return;
}
}
結(jié)尾
以上就是QT實(shí)現(xiàn)UDP協(xié)議通信的全部?jī)?nèi)容了,記得加上network模塊:)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-433502.html
到了這里,關(guān)于【QT網(wǎng)絡(luò)編程】實(shí)現(xiàn)UDP協(xié)議通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!