Qt TCP和UDP通信2

来源:互联网 发布:一组数据 日报 编辑:程序博客网 时间:2024/05/16 15:23

五、UDP

     UDP(User Datagram Protocol)用户数据报协议,是一个轻量级的、不可靠的、面向数据报的、无连接的协议。QUdpSocket实现基于UDP协议的广播应用。适用于:网络数据大多为短信息或拥有大量客户端或对数据安全性无特殊要求或网络负担重对响应速度要求高等。(QQ就使用UDP发消息,所以有时会出现收不到消息的情况)。

1、运行

(1)运行时注意

      发送广播时,先关闭防火墙service iptables stop,或者把改端口号加入到防火墙的允许队列里。使用Qt时要在pro文件中添加QT += network,加入network的模块。

(2)简化图


(3)运行图


  1. pushButton->setEnabled(false);  
  2. }  
  3. void Sender::slotTimeout()  
  4. {  
  5.     QByteArray msg = "hello world!";  
  6.     quint32 port = 8888;  
  7.     int length = sender->writeDatagram(msg, msg.length(), QHostAddress::Broadcast, port);  
  8.   
  9.     if (length != msg.length()) {  
  10.         return;  
  11.     }  
  12. }  

(2)UDP客户端

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <QtGui/QApplication>  
  2. #include "receiver.h"  
  3.   
  4. int main(int argc, char *argv[])  
  5. {  
  6.     QApplication a(argc, argv);  
  7.     Receiver w;  
  8.     w.show();  
  9.   
  10.     return a.exec();  
  11. }  
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #ifndef RECEIVER_H  
  2. #define RECEIVER_H  
  3.   
  4. #include <QDialog>  
  5. #include <QTextEdit>  
  6.   
  7. class QUdpSocket;  
  8.   
  9. namespace Ui {  
  10.     class Receiver;  
  11. }  
  12.   
  13. class Receiver : public QDialog  
  14. {  
  15.     Q_OBJECT  
  16.   
  17. public:  
  18.     explicit Receiver(QWidget *parent = 0);  
  19.     ~Receiver();  
  20.   
  21. private:  
  22.     Ui::Receiver *ui;  
  23.     QUdpSocket *receiver;  
  24.     quint32 port;  
  25.     QTextEdit *reveiveData;  
  26.   
  27. private slots:  
  28.     void dataReceived();  
  29. };  
  30.   
  31. #endif // RECEIVER_H  
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include "receiver.h"  
  2. #include "ui_receiver.h"  
  3. #include <QtNetwork>  
  4. #include <QMessageBox>  
  5.   
  6. Receiver::Receiver(QWidget *parent) :  
  7.     QDialog(parent),  
  8.     ui(new Ui::Receiver)  
  9. {  
  10.     ui->setupUi(this);  
  11.     reveiveData = new QTextEdit(this);  
  12.   
  13.     receiver = new QUdpSocket(this);  
  14.     connect(receiver, SIGNAL(readyRead()), this, SLOT(dataReceived()));  
  15.   
  16.     port = 8888;  
  17.     if (!receiver->bind(port, QUdpSocket::ShareAddress)) {  
  18.         QMessageBox::information(this,tr("error"),tr("udp socket create error!"));  
  19.         return;  
  20.     }  
  21. }  
  22.   
  23. Receiver::~Receiver()  
  24. {  
  25.     delete ui;  
  26. }  
  27.   
  28. // 处理等待的数据报  
  29. void Receiver::dataReceived()  
  30. {  
  31.     // 拥有等待的数据报  
  32.     while(receiver->hasPendingDatagrams()) {  
  33.         QByteArray datagram;     
  34.         QHostAdress sender;   //客户端sender.toString()IP地址  
  35.         qunit16 senderPort;   //客户端端口  
  36.          // 让datagram的大小为等待处理的数据报的大小,这样才能接收到完整的数据   
  37.         datagram.resize(receiver->pendingDatagramSize());   
  38.         // 接收数据报,将其存放到datagram中   
  39.         receiver->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); reveiveData->append(datagram);   
  40.     }  
  41. }  

3、其他UDP代码

UDP服务器和客户端使用相同的代码。其运行结果如下图所示。


[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <QCoreApplication>  
  2. #include "myudp.h"  
  3.   
  4. int main(int argc, char *argv[])  
  5. {  
  6.     QCoreApplication a(argc, argv);  
  7.     MyUDP server;  
  8.     MyUDP client;  
  9.   
  10.     client.SayHello();  
  11.   
  12.     return a.exec();  
  13. }  
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #ifndef MYUDP_H  
  2. #define MYUDP_H  
  3.   
  4. #include <QObject>  
  5. #include <QUdpSocket>  
  6.   
  7. class MyUDP : public QObject  
  8. {  
  9.     Q_OBJECT  
  10. public:  
  11.     explicit MyUDP(QObject *parent = 0);  
  12.     void SayHello();  
  13.   
  14. private:  
  15.     QUdpSocket *socket;  
  16.   
  17. signals:  
  18.   
  19. public slots:  
  20.     void readyRead();  
  21.   
  22. };  
  23.   
  24. #endif // MYUDP_H  
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <QUdpSocket>  
  2. #include "myudp.h"  
  3.   
  4. MyUDP::MyUDP(QObject *parent) :  
  5.     QObject(parent)  
  6. {  
  7.     socket = new QUdpSocket(this);  
  8.     socket->bind(QHostAddress::LocalHost, 1234);  
  9.     connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));  
  10. }  
  11.   
  12. void MyUDP::SayHello()  
  13. {  
  14.     QByteArray Data;  
  15.     Data.append("Hello from UDP Land");  
  16.     socket->writeDatagram(Data, QHostAddress::LocalHost, 1234);  
  17. }  
  18.   
  19. void MyUDP::readyRead()  
  20. {  
  21.     QByteArray Buffer;  
  22.     Buffer.resize(socket->pendingDatagramSize());  
  23.   
  24.     QHostAddress sender;  
  25.     quint16 senderPort;  
  26.     socket->readDatagram(Buffer.data(), Buffer.size(), &sender, &senderPort);  
  27.   
  28.     qDebug() << "Message from:" << sender.toString();  
  29.     qDebug() << "Message port:" << senderPort;  
  30.     qDebug() << "Message:" << Buffer;  
  31. }  

六、UDP总结

        QUdpSocket类用来发送和接收UDP数据报,继承自QAbstractSocket。用于可靠性不是很重要的情况,如一个服务器报告一天的时间,如果数据报丢失,客户端可以简单的发送另外一个请求。UDP相对与TCP效率高,编码也比较简单些。

七、总结

(1)TCP、UDP涉及的内容众多,不同的编码方式使得服务器、客户端的效率性能差别很大,要想写出高效的程序,可以引入非阻塞、事件监听、多线程、线程池等技术。

(2)Qt网络模块依靠其特有的事件循环机制实现了异步模式的网络编程,比直接使用操作系统套接字相比会牺牲一定的效率。

(3)源码已经上传到csdn上可登录下载:

http://download.csdn.net/detail/u014746838/9791754
0 0
原创粉丝点击