前言:前一篇讲了TCP通信,这篇来看看UDP通信。

这里说明一下,UDP通信中分为三种通信分别为单播、组播和广播,下面将一一为大家介绍。

同样的我们都需要在工程文件中添加network

QT       += core gui network

进行UDP通信需要用到的头文件

#include <QUdpSocket>

这里我们把UDP通信分为两个部分写,一个是发送端,另一个是接收端,而发送端中又分为单播、组播和广播三种形式,下面我们先来看看写发送端的代码程序的步骤:

发送端Udpsend的代码:

1、单播

(1)创建套接字

QUdpSocket mSocket;
mSocket = new QUdpSocket();

(2)发送数据到指定的地址和端口号

mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("192.168.137.1"),6677);
参数:ui->textEdit->toPlainText().toUtf8 要发送的消息
QHostAddress("192.168.137.1") 接收端的ip地址
6677 端口号,要和接收端的一致

2、组播,组播和单播的步骤是一样的,只有ip地址处有区别

组播ip地址范围:224.0.0.0-239.255.255.255
例子:mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("224.0.0.100"),);

3、广播,广播也只有ip地址和单播有区别

广播地址ip:QHostAddress::Broadcast
例子:mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress::Broadcast,6677);

好了,单播、组播和广播的区别应该都了解了,那么我们就来看发送端(udpsend.cpp)的具体代码:

 #include "udpsend.h"
#include "ui_udpsend.h" UdpSend:: UdpSend(QWidget *parent) :
QMainWindow(parent),
ui(new Ui:: UdpSend)
{
ui->setupUi(this); //初始化创建QUdpSocket对象
mSocket = new QUdpSocket();
} UdpSend::~ UdpSend()
{
delete ui;
} void UdpSend::on_sendBt_clicked()
{
//单播
// qint64 len = mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("192.168.137.1"),6677); //组播ip地址范围:224.0.0.0-239.255.255.255
//qint64 len = mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("224.0.0.100"),6677); //广播
qint64 len = mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress::Broadcast,); }

发送端的界面文件我做的很简单,我只做了发送消息框:

看完发送端的代码,我们继续来看接收端的代码(Udprecv)

接收端不管是单播、或者组播还是广播代码都是一样的,下面是写接收端代码的步骤:

1、创建套接字

QUdpSocket mSocket;
mSocket = new QUdpSocket();

2、绑定地址和端口号

mSocket->bind(QHostAddress::AnyIPv4,);
参数:AnyIPv4 IPv4
端口号,要和发送端的一致

3、等待数据的到来,利用readyRread()

connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_data()));

4、读数据

readDatagram(char * data, qint64 maxSize, QHostAddress * address = , quint16 * port = )
参数:
data:数据
maxSize:数据的大小
address:QHostAddress类型的地址
port:端口号 例子:
void UdpRecv::read_data()
{
QByteArray array;
QHostAddress address;
quint16 port;
array.resize(mSocket->bytesAvailable());//根据可读数据来设置空间大小
mSocket->readDatagram(array.data(),array.size(),&address,&port); //读取数据
ui->listWidget->addItem(array);//显示数据
//发送反馈数据 }

如果是组播的话还涉及到加入组播和退出组播

加入到组播组  joinMulticastGroup
例子:mSocket->joinMulticastGroup(QHostAddress("224.0.0.100"));
退出组播组 leaveMulticastGroup
例子: mSocket->leaveMulticastGroup(QHostAddress("224.0.0.100"));

来看看接收端(Udprecv.cpp)具体实现的代码

 #include "udprecv.h"
#include "ui_udprecv.h" UdpRecv::UdpRecv(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::UdpRecv)
{
ui->setupUi(this); //创建对象 初始化
mSocket = new QUdpSocket(); //绑定
mSocket->bind(QHostAddress::AnyIPv4,);
//关联读数据信号readyread
connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_data())); } UdpRecv::~UdpRecv()
{
delete ui;
} void UdpRecv::read_data()
{
QByteArray array;
QHostAddress address;
quint16 port;
array.resize(mSocket->bytesAvailable());//根据可读数据来设置空间大小
mSocket->readDatagram(array.data(),array.size(),&address,&port); //读取数据
ui->listWidget->addItem(array);//显示数据
//发送反馈数据 } void UdpRecv::on_checkBox_clicked(bool checked)
{
if(checked)
{
//加入组播
mSocket->joinMulticastGroup(QHostAddress("224.0.0.100"));
} else
{
//退出组播
mSocket->leaveMulticastGroup(QHostAddress("224.0.0.100")); } }

接收端的界面文件我只加了显示接收到的信息和选择是否加入组播的选择按钮

这是发送端和接收分开来写的,此外我也实现了一下发送端和接收端写到同一个文件中

头文件qudpapp.h中的代码

 #ifndef QUDPAPP_H
#define QUDPAPP_H #include <QWidget>
#include <QUdpSocket>
namespace Ui {
class QUdpApp;
} class QUdpApp : public QWidget
{
Q_OBJECT public:
explicit QUdpApp(QWidget *parent = );
~QUdpApp(); private slots:
void on_sendSigRb_clicked(); //单播旋转轴
void on_sendMulRb_clicked(); //组播选择
void on_sendBroadRb_clicked(); //广播选择
void on_sendBt_clicked(); //发送按钮 //===========================================
void on_recvCb_clicked(bool checked); //选择接收
void on_recvJoinMulBt_clicked(); //加入组播
void on_recvLeaveMulBt_clicked(); //退出组播 void on_sendMesEdit_cursorPositionChanged();//检测消息框是否有数据
void read_data(); private:
Ui::QUdpApp *ui;
QUdpSocket *mSocket;
QHostAddress sendaddrees;
QString sendPort; }; #endif // QUDPAPP_H

源文件qudpapp.cpp中的代码

 #include "qudpapp.h"
#include "ui_qudpapp.h"
#include <QMessageBox>
QUdpApp::QUdpApp(QWidget *parent) :
QWidget(parent),
ui(new Ui::QUdpApp)
{
ui->setupUi(this);
mSocket = new QUdpSocket();//创建套接字
ui->sendBt->setEnabled(false);
} QUdpApp::~QUdpApp()
{
delete ui;
} //==========================发送端====================
//单播选择
void QUdpApp::on_sendSigRb_clicked()
{
if(ui->sendPortEdit->text().isEmpty() || ui->sendSigAddrEdit->text().isEmpty())
{
QMessageBox::warning(this,"提示","请输入单播ip和端口号");
//ui->sendSigRb->setChecked(false);
return;
}
sendaddrees.setAddress( ui->sendSigAddrEdit->text());
sendPort = ui->sendPortEdit->text(); } //组播选择
void QUdpApp::on_sendMulRb_clicked()
{
if(ui->sendPortEdit->text().isEmpty() || ui->sendMulAddrEdit->text().isEmpty())
{
QMessageBox::warning(this,"提示","请输入组播ip和端口号");
//ui->sendSigRb->setChecked(false);
return;
}
sendaddrees.setAddress( ui->sendMulAddrEdit->text());
sendPort = ui->sendPortEdit->text(); } //广播选择
void QUdpApp::on_sendBroadRb_clicked()
{
if(ui->sendPortEdit->text().isEmpty() || ui->sendBroadAddrEdit->text().isEmpty())
{
QMessageBox::warning(this,"提示","请输入广播ip和端口号");
//ui->sendSigRb->setChecked(false);
return;
}
sendaddrees.setAddress( ui->sendBroadAddrEdit->text());
sendPort = ui->sendPortEdit->text(); } //发送按钮
void QUdpApp::on_sendBt_clicked()
{
mSocket->writeDatagram(ui->sendMesEdit->toPlainText().toUtf8(),sendaddrees,sendPort.toInt()); } //检测发送消息对话框中是否有消息
void QUdpApp::on_sendMesEdit_cursorPositionChanged()
{
if(ui->sendMesEdit->toPlainText().isEmpty())
{
ui->sendBt->setEnabled(false);
}
else
{
ui->sendBt->setEnabled(true);
} } //==========================发送端==================== //==========================接收端===================== //选择接收
void QUdpApp::on_recvCb_clicked(bool checked)
{
if(ui->recvPortEdit->text().isEmpty())
{
QMessageBox::warning(this,"提示","请输入端口号");
ui->recvCb->setChecked(false);
return;
}
if(checked)
{
mSocket->bind(QHostAddress::AnyIPv4,ui->recvPortEdit->text().toInt());
connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_data()));
ui->recvPortEdit->setEnabled(false);
}
else
{
mSocket->close();
ui->recvPortEdit->setEnabled(true);
}
} //加入组播
void QUdpApp::on_recvJoinMulBt_clicked()
{
if(ui->recvMulAddrEdit->text().isEmpty())
{
QMessageBox::warning(this,"提示","请输入组播ip");
return;
}
if(mSocket->joinMulticastGroup(QHostAddress(ui->recvMulAddrEdit->text()))) //加入组播
{
ui->recvMulAddr->addItem(ui->recvMulAddrEdit->text());
}
else
{
QMessageBox::warning(this,"提示","加入组播失败,请修改ip后继续加入");
//return;
} } //退出组播
void QUdpApp::on_recvLeaveMulBt_clicked()
{
mSocket->leaveMulticastGroup(QHostAddress(ui->recvMulAddr->currentIndex()));//退出组播地址列表当前的组播
ui->recvMulAddr->removeItem(ui->recvMulAddr->currentIndex()); //删除组播地址列表中当前的组播地址
} void QUdpApp::read_data()
{
QByteArray array;
array.resize(mSocket->bytesAvailable()); //将接收数据的array设置成为要接收数据的大小
QHostAddress recvaddress;
quint16 port;
mSocket->readDatagram(array.data(),array.size(),&recvaddress,&port); //读取数据
ui->recvList->addItem(array); } //==========================接收端=====================

界面文件qudpapp.ui

 <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QUdpApp</class>
<widget class="QWidget" name="QUdpApp">
<property name="geometry">
<rect>
<x></x>
<y></y>
<width></width>
<height></height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch></horstretch>
<verstretch></verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>QUdpApp</string>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x></x>
<y></y>
<width></width>
<height></height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch></horstretch>
<verstretch></verstretch>
</sizepolicy>
</property>
<property name="title">
<string>发送端</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number></number>
</property>
<property name="leftMargin">
<number></number>
</property>
<property name="topMargin">
<number></number>
</property>
<property name="rightMargin">
<number></number>
</property>
<property name="bottomMargin">
<number></number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number></number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>端 口 号</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="sendPortEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch></horstretch>
<verstretch></verstretch>
</sizepolicy>
</property>
<property name="placeholderText">
<string>请输入端口号</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number></number>
</property>
<item>
<widget class="QRadioButton" name="sendSigRb">
<property name="text">
<string>单播</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="sendSigAddrEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch></horstretch>
<verstretch></verstretch>
</sizepolicy>
</property>
<property name="placeholderText">
<string>请输入接收方地址</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number></number>
</property>
<item>
<widget class="QRadioButton" name="sendMulRb">
<property name="text">
<string>组播</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="sendMulAddrEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch></horstretch>
<verstretch></verstretch>
</sizepolicy>
</property>
<property name="placeholderText">
<string>请输入组播地址</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number></number>
</property>
<item>
<widget class="QRadioButton" name="sendBroadRb">
<property name="text">
<string>广播</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="sendBroadAddrEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch></horstretch>
<verstretch></verstretch>
</sizepolicy>
</property>
<property name="placeholderText">
<string>请输入广播地址</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch></horstretch>
<verstretch></verstretch>
</sizepolicy>
</property>
<property name="title">
<string>接收端</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QCheckBox" name="recvCb">
<property name="text">
<string>接收</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="recvPortEdit">
<property name="placeholderText">
<string>请输入端口号</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number></number>
</property>
<item>
<widget class="QLineEdit" name="recvMulAddrEdit">
<property name="placeholderText">
<string>输入要加入的组播地址</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="recvJoinMulBt">
<property name="maximumSize">
<size>
<width></width>
<height></height>
</size>
</property>
<property name="text">
<string>加入</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QComboBox" name="recvMulAddr"/>
</item>
<item>
<widget class="QPushButton" name="recvLeaveMulBt">
<property name="maximumSize">
<size>
<width></width>
<height></height>
</size>
</property>
<property name="text">
<string>退出</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QListWidget" name="recvList"/>
</item>
<item>
<widget class="QTextEdit" name="sendMesEdit">
<property name="maximumSize">
<size>
<width></width>
<height></height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QPushButton" name="clearRecvListBt">
<property name="text">
<string>清除接收区</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearsendEditBt">
<property name="text">
<string>清除发送区</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="">
<size>
<width></width>
<height></height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="sendBt">
<property name="text">
<string>发送</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="" margin=""/>
<resources/>
<connections>
<connection>
<sender>clearRecvListBt</sender>
<signal>clicked()</signal>
<receiver>recvList</receiver>
<slot>clear()</slot>
<hints>
<hint type="sourcelabel">
<x></x>
<y></y>
</hint>
<hint type="destinationlabel">
<x></x>
<y></y>
</hint>
</hints>
</connection>
<connection>
<sender>clearsendEditBt</sender>
<signal>clicked()</signal>
<receiver>sendMesEdit</receiver>
<slot>clear()</slot>
<hints>
<hint type="sourcelabel">
<x></x>
<y></y>
</hint>
<hint type="destinationlabel">
<x></x>
<y></y>
</hint>
</hints>
</connection>
</connections>
</ui>

界面文件图示

最新文章

  1. Android应用开发-Activity(重制版)
  2. Android学习---SQLite数据库的增删改查和事务(transaction)调用
  3. 如何解决requireJs的模块加载超时
  4. Windows 设置扩展投影鼠标移出方向
  5. Troubleshoot Refused VNC Connection in CentOS 7
  6. Android activity属性
  7. ListView蛮好用
  8. webapp开发经验和资料
  9. User cannot be resolved to a type
  10. 第一个输出程序 Console.WriteLine
  11. ACM比赛(进制转换)
  12. MyEclipse 2015 运行tomcat 内存溢出的解决方法
  13. 新版netkeeper开wifi无需路由器
  14. 动态 DP 学习笔记
  15. JavaScript前端面试题总结
  16. Linux创建用户与权限赋值
  17. View体系之属性动画
  18. [Selenium Grid] 搭建Hub和Node环境
  19. [UI] 精美UI界面欣赏[4]
  20. hdu 1159(DP+字符串最长公共序列)

热门文章

  1. 写了一个bug,最后却变成了feature,要不要修呢?
  2. 最新版multer1.3.0上传文件
  3. Entropy
  4. 0_Simple__simpleAssert + 0_Simple__simpleAssert_nvrtc
  5. aria-label
  6. python利用django实现简单的登录和注册,并利用session实现了链接数据库
  7. 实现一个websocket服务器-理论篇
  8. C#读取数据库返回泛型集合(DataSetToList)
  9. linux操作系统基础篇(八)
  10. VMWare安装Centos 6.9