Qt浅谈之十六:TCP和UDP(之二)
来源:互联网 发布:炭知天下龙泽路手机号 编辑:程序博客网 时间:2024/05/01 18:01
五、UDP
UDP(User Datagram Protocol)用户数据报协议,是一个轻量级的、不可靠的、面向数据报的、无连接的协议。QUdpSocket实现基于UDP协议的广播应用。适用于:网络数据大多为短信息或拥有大量客户端或对数据安全性无特殊要求或网络负担重对响应速度要求高等。(QQ就使用UDP发消息,所以有时会出现收不到消息的情况)。
1、运行
(1)运行时注意
发送广播时,先关闭防火墙service iptables stop,或者把改端口号加入到防火墙的允许队列里。使用Qt时要在pro文件中添加QT += network,加入network的模块。
(2)简化图
(3)运行图
服务器发送广播,客户端接收广播信息,并显示在窗口上。
2、代码
(1)UDP服务器端(完整代码在csdn上)如果只想发送数据时,就不需要调用bind()。
#include <QtGui/QApplication>#include "sender.h"int main(int argc, char *argv[]){ QApplication a(argc, argv); Sender w; w.show(); return a.exec();}
#ifndef SENDER_H#define SENDER_H#include <QDialog>class QUdpSocket;namespace Ui { class Sender;}class Sender : public QDialog{ Q_OBJECTpublic: explicit Sender(QWidget *parent = 0); ~Sender();private slots: void on_pushButton_clicked(); void slotTimeout();private: Ui::Sender *ui; QUdpSocket *sender; QTimer *timer;};#endif // SENDER_H
#include "sender.h"#include "ui_sender.h"#include <QtNetwork>Sender::Sender(QWidget *parent) : QDialog(parent), ui(new Ui::Sender){ ui->setupUi(this); sender = new QUdpSocket(this); timer = new QTimer(this); connect(timer,SIGNAL(timeout()),this,SLOT(slotTimeout()));}Sender::~Sender(){ delete ui;}void Sender::on_pushButton_clicked(){ timer->start(1000); ui->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_OBJECTpublic: 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; //客户端sender.toString()IP地址 qunit16 senderPort; //客户端端口 // 让datagram的大小为等待处理的数据报的大小,这样才能接收到完整的数据 datagram.resize(receiver->pendingDatagramSize()); // 接收数据报,将其存放到datagram中 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_OBJECTpublic: 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/taiyang1987912/7744759)。
(4)若有更好的设计建议或需要其他的源码,可发邮件沟通!邮箱地址yang.ao@i-soft.com.cn。
- Qt浅谈之十六:TCP和UDP(之二)
- Qt浅谈之十六:TCP和UDP(之一)
- Qt浅谈之二十六图片滑动效果
- qt之tcp(二)
- (二十六)Qt容器之顺序容器
- Qt之TCP、UDP传输模型
- TCP和UDP之面试
- tcp和udp(二)
- Qt浅谈之二十九Qt多线程
- Windows网络编程之(二)Socket通信非阻塞模式Select(TCP和UDP)
- 浅谈TCP和UDP区别
- android 之浅谈UDP与TCP网络编程
- 我和我女朋友之二十六
- 【计算机网络学习】之TCP和UDP比较
- Udp打洞和TCP打洞之我见
- Java 网络编程之TCP和UDP
- Java之网络编程UDP和TCP
- java个人笔记之UDP和TCP
- 我为什么写博客
- Dividing hdu acm 1059 c++
- oracle 笔记 游标
- C++中如何根据多个字节读取二进制文件
- 上海传智播客JAVASE_day09学习笔记
- Qt浅谈之十六:TCP和UDP(之二)
- 用到哪学到哪------Thinkphp ajaxReturn的数据类型
- PL/SQL编程基础
- 字符串的排列
- 12,activity 屏幕触摸汇总
- WinForm自定义弹出框边角圆滑处理
- 吴大全案
- CH Round #49 - Streaming #4 (NOIP模拟赛Day2)
- 一只小蜜蜂...(2044)