UDP是無(wú)連接的不可靠的傳輸協(xié)議,可以用在可靠傳輸不是很重要的情況下使用。 QUdpSocket是QAbstractSocket 的子類,它們都繼承了QIODevice。所以可以用QUdpSocket進(jìn)行發(fā)送接收數(shù)據(jù)。它和QTcpSocket最大的區(qū)別也就是,發(fā)送數(shù)據(jù)之前不需要建立連接
以下簡(jiǎn)單例子,演示了用QUdpSocket如何實(shí)現(xiàn)客戶端和服務(wù)端的通信。
服務(wù)端代碼:
[cpp] view plain copy
1. class UDPServer:public QObject
2. {
3. Q_OBJECT
4. public:
5. UDPServer(QObject *parent = NULL);
6. ~UDPServer();
7. private slots:
8. void readPendingDatagrams();
9. private:
10. QUdpSocket *udpSocket;
11.
12. };
[cpp] view plain copy
1. UDPServer::UDPServer(QObject *parent /* = NULL */):QObject(parent)
2. {
3. udpSocket = new QUdpSocket(this);
4. udpSocket-》bind(QHostAddress::LocalHost, 7755);
5. cout《《“Server is Running.。。。。。”《《endl;
6. connect(udpSocket, SIGNAL(readyRead()),this, SLOT(readPendingDatagrams()));
7. }
8.
9. UDPServer::~UDPServer()
10. {
11.
12. }
13.
14. void UDPServer::readPendingDatagrams()
15. {
16. QHostAddress sender;
17. quint16 senderPort;
18. while (udpSocket-》hasPendingDatagrams())
19. {
20. QByteArray datagram;
21. datagram.resize(udpSocket-》pendingDatagramSize());
22. udpSocket-》readDatagram(datagram.data(), datagram.size(),&sender, &senderPort);
23. string strMes(datagram);
24. std::cout《《strMes《《endl;
25. }
26. QString text = “hello 。。。”;
27. QByteArray datagram = text.toLocal8Bit();
28. udpSocket-》writeDatagram(datagram.data(),datagram.size(),sender, senderPort);
29. }
說(shuō)明:
1. 我都是在自己的機(jī)器上測(cè)試,所以服務(wù)器地址都是localHost。即
[cpp] view plain copy
udpSocket-》bind(QHostAddress::LocalHost, 7755);
2. 給客戶端回發(fā)信息
[cpp] view plain copy
udpSocket-》writeDatagram(datagram.data(),datagram.size(),sender, senderPort);
客戶端代碼:
[cpp] view plain copy
1. class UdpClient : public QWidget
2. {
3. Q_OBJECT
4.
5. public:
6. UdpClient(QWidget *parent = 0, Qt::WFlags flags = 0);
7. ~UdpClient();
8.
9. private slots:
10. void sendMessageSlot();
11. void readPendingDatagrams();
12. private:
13. QUdpSocket *udpSocket;
14. QLineEdit *m_pLEdit;
15. QPushButton *m_pSendMesBtn;
16. QLabel *m_pMessage;
18. };
[cpp] view plain copy
1. UdpClient::UdpClient(QWidget *parent, Qt::WFlags flags)
2. : QWidget(parent, flags)
3. {
4. m_pLEdit = new QLineEdit(this);
5. m_pSendMesBtn = new QPushButton(tr(“Sending”),this);
6. udpSocket = new QUdpSocket(this);
7. m_pMessage = new QLabel(this);
8. QHostAddress sender = udpSocket-》localAddress();
9. quint16 senderPort = udpSocket-》localPort();
10. udpSocket-》bind(sender,senderPort);
11. m_pLEdit-》setGeometry(5,5,100,20);
12. m_pSendMesBtn-》setGeometry(110,5,50,20);
13. m_pMessage-》setGeometry(5,30,150,20);
14. m_pLEdit-》setStyleSheet(“QLineEdit{color:red}”);
15. connect(m_pSendMesBtn, SIGNAL(clicked()),this, SLOT(sendMessageSlot()));
16. connect(udpSocket, SIGNAL(readyRead()),this, SLOT(readPendingDatagrams())); 19.
20. }
21.
22. UdpClient::~UdpClient()
23. {
24.
25. }
26.
27. void UdpClient::sendMessageSlot()
28. {
29. QString text = m_pLEdit-》text();
30. QByteArray datagram = text.toLocal8Bit();
31. udpSocket-》writeDatagram(datagram.data(),datagram.size(),QHostAddress::LocalHost, 7755);
32. }
33.
34. void UdpClient::readPendingDatagrams()
35. {
36. while (udpSocket-》hasPendingDatagrams())
37. {
38. QByteArray datagram;
39. datagram.resize(udpSocket-》pendingDatagramSize());
40. QHostAddress sender;
41. quint16 senderPort;
42. udpSocket-》readDatagram(datagram.data(), datagram.size(),&sender, &senderPort);
43. QString text = QString(datagram);
44. m_pMessage-》setText(text);
45. }
46. }
說(shuō)明:
1. 綁定本地地址和端口,以接收客戶端發(fā)過(guò)來(lái)的信息
[cpp] view plain copy
a. QHostAddress sender = udpSocket-》localAddress();
b. quint16 senderPort = udpSocket-》localPort();
c. udpSocket-》bind(sender,senderPort);
QUdpSocket簡(jiǎn)單使用Demo(局域網(wǎng)內(nèi)發(fā)送給所有客戶端消息與接收)
先看一下效果:
服務(wù)端和客戶端都用到一個(gè)公共類:
UDPServerAndClient.h:
#ifndef UDPSERVERANDCLIENT_H
#define UDPSERVERANDCLIENT_H
#include 《QObject》
#include 《QUdpSocket》
#include 《QTimer》
class UDPServerAndClient : public QObject
{
Q_OBJECT
public:
explicit UDPServerAndClient(QObject *parent = 0);
void setServerInit();
void setClientInit();
private slots:
void onPendingDatagrams();
private:
QUdpSocket udpSocketServer;
QUdpSocket udpSocketClient;
QTimer timer;
};
#endif // UDPSERVERANDCLIENT_H
UDPServerAndClient.cpp:
#include “udpserverandclient.h”
#include 《QHostInfo》
#include 《QDataStream》
#include 《QDateTime》
UDPServerAndClient::UDPServerAndClient(QObject *parent) : QObject(parent)
{
}
void UDPServerAndClient::setServerInit()
{
connect(&timer, SIGNAL(timeout()), this, SLOT(onServerSendBroadcast())); //定時(shí)發(fā)送
timer.start(2000);
}
void UDPServerAndClient::setClientInit()
{
udpSocketClient.bind(13999); //建立監(jiān)聽(tīng)
connect(&udpSocketClient, SIGNAL(readyRead()), this, SLOT(onPendingDatagrams())); //接收準(zhǔn)備
}
void UDPServerAndClient::onServerSendBroadcast()
{
QByteArray datagram;
QDataStream out(&datagram, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_6);
out 《《 QDateTime::currentDateTime() 《《 QHostInfo::fromName(QHostInfo::localHostName()).addresses().last().toString();
//發(fā)送主機(jī)可以用QHostAddress(“127.0.0.1”)替換
udpSocketServer.writeDatagram(datagram, QHostAddress::Broadcast, 13999); // UDP 發(fā)送數(shù)據(jù)
}
void UDPServerAndClient::onPendingDatagrams()
{
QByteArray datagram;
do{
datagram.resize(udpSocketClient.pendingDatagramSize());
udpSocketClient.readDatagram(datagram.data(), datagram.size()); //接收數(shù)據(jù)
} while( udpSocketClient.hasPendingDatagrams() );
QDateTime dateTime;
QString lastIP;
QDataStream in(&datagram, QIODevice::ReadOnly);
in.setVersion(QDataStream::Qt_5_6);
in 》》 dateTime 》》 lastIP;
qDebug() 《《“dateTime.date().toString():” 《《 dateTime.date().toString()
《《“ip:” 《《 lastIP;
}
評(píng)論
查看更多