五、UDP
UDP(User Datagram Protocol)用户数据报协议,是一个轻量级的、不可靠的、面向数据报的、无连接的协议。QUdpSocket实现基于UDP协议的广播应用。适用于:网络数据大多为短信息或拥有大量客户端或对数据安全性无特殊要求或网络负担重对响应速度要求高等。(QQ就使用UDP发消息,所以有时会出现收不到消息的情况)。
1、运行
(1)运行时注意
发送广播时,先关闭防火墙service iptables stop,或者把改端口号加入到防火墙的允许队列里。使用Qt时要在pro文件中添加QT += network,加入network的模块。
(2)简化图
(3)运行图
- pushButton->setEnabled(false);
- }
- void Sender::slotTimeout()
- {
- QByteArray msg = "hello world!";
- quint32 port = 8888;
- int length = sender->writeDatagram(msg, msg.length(), QHostAddress::Broadcast, port);
-
- if (length != msg.length()) {
- return;
- }
- }
(2)UDP客户端
- #include <QtGui/QApplication>
- #include "receiver.h"
-
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- Receiver w;
- w.show();
-
- return a.exec();
- }
- #ifndef RECEIVER_H
- #define RECEIVER_H
-
- #include <QDialog>
- #include <QTextEdit>
-
- class QUdpSocket;
-
- namespace Ui {
- class Receiver;
- }
-
- class Receiver : public QDialog
- {
- Q_OBJECT
-
- public:
- explicit Receiver(QWidget *parent = 0);
- ~Receiver();
-
- private:
- Ui::Receiver *ui;
- QUdpSocket *receiver;
- quint32 port;
- QTextEdit *reveiveData;
-
- private slots:
- void dataReceived();
- };
-
- #endif // RECEIVER_H
- #include "receiver.h"
- #include "ui_receiver.h"
- #include <QtNetwork>
- #include <QMessageBox>
-
- Receiver::Receiver(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Receiver)
- {
- ui->setupUi(this);
- reveiveData = new QTextEdit(this);
-
- receiver = new QUdpSocket(this);
- connect(receiver, SIGNAL(readyRead()), this, SLOT(dataReceived()));
-
- port = 8888;
- if (!receiver->bind(port, QUdpSocket::ShareAddress)) {
- QMessageBox::information(this,tr("error"),tr("udp socket create error!"));
- return;
- }
- }
-
- Receiver::~Receiver()
- {
- delete ui;
- }
-
-
- void Receiver::dataReceived()
- {
-
- while(receiver->hasPendingDatagrams()) {
- QByteArray datagram;
- QHostAdress sender;
- qunit16 senderPort;
-
- datagram.resize(receiver->pendingDatagramSize());
-
- receiver->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); reveiveData->append(datagram);
- }
- }
3、其他UDP代码
UDP服务器和客户端使用相同的代码。其运行结果如下图所示。
- #include <QCoreApplication>
- #include "myudp.h"
-
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- MyUDP server;
- MyUDP client;
-
- client.SayHello();
-
- return a.exec();
- }
- #ifndef MYUDP_H
- #define MYUDP_H
-
- #include <QObject>
- #include <QUdpSocket>
-
- class MyUDP : public QObject
- {
- Q_OBJECT
- public:
- explicit MyUDP(QObject *parent = 0);
- void SayHello();
-
- private:
- QUdpSocket *socket;
-
- signals:
-
- public slots:
- void readyRead();
-
- };
-
- #endif // MYUDP_H
- #include <QUdpSocket>
- #include "myudp.h"
-
- MyUDP::MyUDP(QObject *parent) :
- QObject(parent)
- {
- socket = new QUdpSocket(this);
- socket->bind(QHostAddress::LocalHost, 1234);
- connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
- }
-
- void MyUDP::SayHello()
- {
- QByteArray Data;
- Data.append("Hello from UDP Land");
- socket->writeDatagram(Data, QHostAddress::LocalHost, 1234);
- }
-
- void MyUDP::readyRead()
- {
- QByteArray Buffer;
- Buffer.resize(socket->pendingDatagramSize());
-
- QHostAddress sender;
- quint16 senderPort;
- socket->readDatagram(Buffer.data(), Buffer.size(), &sender, &senderPort);
-
- qDebug() << "Message from:" << sender.toString();
- qDebug() << "Message port:" << senderPort;
- qDebug() << "Message:" << Buffer;
- }
六、UDP总结
QUdpSocket类用来发送和接收UDP数据报,继承自QAbstractSocket。用于可靠性不是很重要的情况,如一个服务器报告一天的时间,如果数据报丢失,客户端可以简单的发送另外一个请求。UDP相对与TCP效率高,编码也比较简单些。
七、总结
(1)TCP、UDP涉及的内容众多,不同的编码方式使得服务器、客户端的效率性能差别很大,要想写出高效的程序,可以引入非阻塞、事件监听、多线程、线程池等技术。
(2)Qt网络模块依靠其特有的事件循环机制实现了异步模式的网络编程,比直接使用操作系统套接字相比会牺牲一定的效率。
(3)源码已经上传到csdn上可登录下载:
http://download.csdn.net/detail/u014746838/9791754