UDP是无连接的不可靠的传输协议,可以用在可靠传输不是很重要的情况下使用。 QUdpSocket是QAbstractSocket 的子类,它们都继承了QIODevice。所以可以用QUdpSocket进行发送接收数据。它和QTcpSocket最大的区别也就是,发送数据之前不需要建立连接
以下简单例子,演示了用QUdpSocket如何实现客户端和服务端的通信。
服务端代码:
[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. }
说明:
1. 我都是在自己的机器上测试,所以服务器地址都是localHost。即
[cpp] view plain copy
udpSocket-》bind(QHostAddress::LocalHost, 7755);
2. 给客户端回发信息
[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. }
说明:
1. 绑定本地地址和端口,以接收客户端发过来的信息
[cpp] view plain copy
a. QHostAddress sender = udpSocket-》localAddress();
b. quint16 senderPort = udpSocket-》localPort();
c. udpSocket-》bind(sender,senderPort);
QUdpSocket简单使用Demo(局域网内发送给所有客户端消息与接收)
先看一下效果:
服务端和客户端都用到一个公共类:
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())); //定时发送
timer.start(2000);
}
void UDPServerAndClient::setClientInit()
{
udpSocketClient.bind(13999); //建立监听
connect(&udpSocketClient, SIGNAL(readyRead()), this, SLOT(onPendingDatagrams())); //接收准备
}
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();
//发送主机可以用QHostAddress(“127.0.0.1”)替换
udpSocketServer.writeDatagram(datagram, QHostAddress::Broadcast, 13999); // UDP 发送数据
}
void UDPServerAndClient::onPendingDatagrams()
{
QByteArray datagram;
do{
datagram.resize(udpSocketClient.pendingDatagramSize());
udpSocketClient.readDatagram(datagram.data(), datagram.size()); //接收数据
} 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;
}
评论
查看更多