IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> QT笔记——网络通信 之 QUdpSocket -> 正文阅读

[网络协议]QT笔记——网络通信 之 QUdpSocket

UDP(用户数据报协议),是一个轻量的,不可靠的,面向数据报的,非连接的协议。当通讯要求的可靠性不重要时(可能数据会丢失),可以用UDP通信

.pro文件中添加网络模块 QT += network
头文件:#include<QUdpSocket>
重要函数:

bind()                   //服务器绑定端口
hasPendingDatagrams()    //当数据发来时,至少有一个数据报需要读取。
writeDatagram(const char *data, qint64 size, const QHostAddress &address, quint16 port)        //函数向指定的地址host和端口port发送数据报datagram,返回成功发送的字节数,数据报不要太长,不要超过512Byte
readDatagram(char *data, qint64 maxSize, QHostAddress *address = nullptr, quint16 *port = nullptr) 
pendingDatagramSize()   //函数第一个待读取的数据报的大小Byte。
joinMulticastGroup()	//函数使socket加入一个多播组groupAddress。
leaveMulticastGroup()   //函数使socket离开多播组groupAddress。

设计一下UI:
在这里插入图片描述
服务器:
1.绑定端口

m_udpSocket->bind(QHostAddress::AnyIPv4,8888);

2.发送消息 和 读取消息
2.1发送消息

//获取信息
QString sendStr = ui.sendTextEdit->toPlainText();
quint16 port = ui.portLineEdit->text().toInt();
QString ip = ui.IPlineEdit->text();
m_udpSocket->writeDatagram(sendStr.toUtf8(), QHostAddress(ip), port);
//连接socket  读取发送过来消息
connect(m_udpSocket, &QUdpSocket::readyRead, this, &QUdpTest::readValue);

2.2读取消息

while (m_udpSocket->hasPendingDatagrams())
{
	QByteArray array;
	//array.resize(m_udpSocket->bytesAvailable());
	array.resize(m_udpSocket->pendingDatagramSize());
	QHostAddress address;
	quint16 port;
	m_udpSocket->readDatagram(array.data(), array.size(),&address,&port);
	qDebug() << QStringLiteral("传过来的大小为:") << array.size();

	//用读取数据流
	//QDataStream read(&array, QIODevice::ReadOnly); 
	//Person p;
	//read >> p.name >> p.age >> p.score ;
	//QString str = QString("%1 %2 %3").arg(QString::number(p.age)).arg(p.name).arg(QString::number(p.score));	
	qDebug() << array.data();
	
	//读取发来的结构体(强转为我们需要转化的结构体)
	Person* p = reinterpret_cast<Person*>(array.data());
	QString str1 = QString(QLatin1String(p->name));
	QString str = QString("%1 %2 %3").arg(QString::number(p->age)).arg(str1).arg(QString::number(p->score));
	ui.recvTextEdit->setText(str);
}

客户端:
1.绑定端口

m_socket->bind(QHostAddress::AnyIPv4,9999);

2.发送消息 和 读取消息
2.1发送消息

quint16 port = ui.portLineEdit->text().toInt();
QString ip = ui.IPLineEdit->text();
QString sendStr = ui.sendTextEdit->toPlainText();
Person p1;
strcpy(p1.name, "xm");
p1.age = 20;
p1.score = 60;

//发送数据流
//QByteArray text_data;
//QDataStream write(&text_data, QIODevice::WriteOnly);
//write << p1.name << p1.age << p1.score ;
//m_socket->writeDatagram(text_data, text_data.size(), QHostAddress(ip), port);

//发送输入框中的内容
//m_socket->writeDatagram(sendStr.toUtf8(),QHostAddress(ip), port);
//m_socket->writeDatagram(sendStr.toLocal8Bit(), sendStr.size(), QHostAddress(ip), port);	

//发送结构体
m_socket->writeDatagram(( char*)&p1, sizeof(Person), QHostAddress(ip), port);
qDebug() << QStringLiteral("发送的数据大小:") << sizeof(p1);

2.2读取消息

while (m_socket->hasPendingDatagrams())
{
	QByteArray array;
	//array.resize(m_socket->bytesAvailable());//根据可读数据来设置空间大小
	array.resize(m_socket->pendingDatagramSize());
	QHostAddress address;
	quint16 port;
	m_socket->readDatagram(array.data(), array.size(), &address, &port);
	ui.recvTextEdit->setText(array);
}

3.客户端和服务端都加入组播
UDP组播是主机间一对一组的通信模式,当多个客户端加入由一个组播地址定义的多播组后,客户端向这个组播地址和端口发送的UDP数据报,组内成员都可以接收到。

m_socket->joinMulticastGroup(QHostAddress("224.0.0.100"));

完整代码:
QUdpTest.h

#pragma once
#include <QtWidgets/QWidget>
#include "ui_QUdpTest.h"
#include <QUdpSocket>
#include <QDebug>
class QUdpTest : public QWidget
{
	Q_OBJECT
	struct Person
	{
		char  name[20];
		int age;
		int score;
		Person()
		{
			memset(name, 0, 20);
			age = 0;
			score = 0;
		}
	};
public:
	QUdpTest(QWidget *parent = Q_NULLPTR);
	~QUdpTest();

public slots:
	  void readValue();
	  void on_sendBtn_clicked();
	  void on_delBtn_clicked();
private:
	Ui::QUdpTestClass ui;
	QUdpSocket* m_udpSocket;
};

QUdpTest.cpp

#include "QUdpTest.h"
#include <QDebug>
#include <QByteArray>
#include <QString>
#include <QLatin1String>
QUdpTest::QUdpTest(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	m_udpSocket = new QUdpSocket(this);

	this->setWindowTitle(QStringLiteral("绑定端口号为:8888"));
	//绑定端口
	m_udpSocket->bind(QHostAddress::AnyIPv4,8888);
	m_udpSocket->joinMulticastGroup(QHostAddress("224.0.0.100"));
	connect(m_udpSocket, &QUdpSocket::readyRead, this, &QUdpTest::readValue);
	ui.recvTextEdit->setReadOnly(true);
}

QUdpTest::~QUdpTest()
{

}

void QUdpTest::readValue()
{
	while (m_udpSocket->hasPendingDatagrams())
	{
		QByteArray array;
		//array.resize(m_udpSocket->bytesAvailable());
		array.resize(m_udpSocket->pendingDatagramSize());
		QHostAddress address;
		quint16 port;
		m_udpSocket->readDatagram(array.data(), array.size(),&address,&port);
		qDebug() << QStringLiteral("传过来的大小为:") << array.size();

		//QDataStream read(&array, QIODevice::ReadOnly);  //读取数据流
		//Person p;
		//read >> p.name >> p.age >> p.score ;
		//QString str = QString("%1 %2 %3").arg(QString::number(p.age)).arg(p.name).arg(QString::number(p.score));
		qDebug() << array.data();
		Person* p = reinterpret_cast<Person*>(array.data());
		QString str1 = QString(QLatin1String(p->name));
		QString str = QString("%1 %2 %3").arg(QString::number(p->age)).arg(str1).arg(QString::number(p->score));
		ui.recvTextEdit->setText(str);
	}
}

void QUdpTest::on_sendBtn_clicked()
{
	//获取信息
	QString sendStr = ui.sendTextEdit->toPlainText();
	quint16 port = ui.portLineEdit->text().toInt();
	QString ip = ui.IPlineEdit->text();
	m_udpSocket->writeDatagram(sendStr.toUtf8(), QHostAddress(ip), port);
}

void QUdpTest::on_delBtn_clicked()
{
	m_udpSocket->leaveMulticastGroup(QHostAddress("224.0.0.100"));
}

QUdpTest1.h

#pragma once
#include <QWidget>
#include "ui_QUdpTest1.h"
#include <QUdpSocket>
class QUdpTest1 : public QWidget
{
	Q_OBJECT
	struct Person
	{
		char  name[20];
		int age;
		int score;
		Person()
		{
			memset(name, 0, 20);
			age = 0;
			score = 0;
		}
	};
public:
	QUdpTest1(QWidget *parent = Q_NULLPTR);
	~QUdpTest1();
public slots:
	void readValue();
	void on_sendBtn_clicked();
	void on_delBtn_clicked();
private:
	Ui::QUdpTest1 ui;
	QUdpSocket* m_socket;
};

QUdpTest1.cpp

#include "QUdpTest1.h"
#include <string.h>
QUdpTest1::QUdpTest1(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	m_socket = new QUdpSocket(this);
	this->setWindowTitle(QStringLiteral("绑定端口为:9999"));
	m_socket->bind(QHostAddress::AnyIPv4,9999);
	m_socket->joinMulticastGroup(QHostAddress("224.0.0.100"));
	connect(m_socket, &QUdpSocket::readyRead, this, &QUdpTest1::readValue);
	ui.recvTextEdit->setReadOnly(true);
}

QUdpTest1::~QUdpTest1()
{
}

void QUdpTest1::readValue()
{
	while (m_socket->hasPendingDatagrams())
	{
		QByteArray array;
		//array.resize(m_socket->bytesAvailable());//根据可读数据来设置空间大小
		array.resize(m_socket->pendingDatagramSize());
		QHostAddress address;
		quint16 port;
		m_socket->readDatagram(array.data(), array.size(), &address, &port);
		ui.recvTextEdit->setText(array);
	}	
}

void QUdpTest1::on_sendBtn_clicked()
{
	quint16 port = ui.portLineEdit->text().toInt();
	QString ip = ui.IPLineEdit->text();
	QString sendStr = ui.sendTextEdit->toPlainText();
	Person p1;
	strcpy(p1.name, "xm");
	p1.age = 20;
	p1.score = 60;

	//QByteArray text_data;
	//QDataStream write(&text_data, QIODevice::WriteOnly);
	//write << p1.name << p1.age << p1.score ;
	//m_socket->writeDatagram(text_data, text_data.size(), QHostAddress(ip), port);

	//m_socket->writeDatagram(sendStr.toUtf8(),QHostAddress(ip), port);
	//m_socket->writeDatagram(sendStr.toLocal8Bit(), sendStr.size(), QHostAddress(ip), port);
	
	m_socket->writeDatagram(( char*)&p1, sizeof(Person), QHostAddress(ip), port);
	qDebug() << QStringLiteral("发送的数据大小:") << sizeof(p1);
}

void QUdpTest1::on_delBtn_clicked()
{
	m_socket->leaveMulticastGroup(QHostAddress("224.0.0.100"));
}

运行结果:
发送文本中的内容:
在这里插入图片描述
发送结构体中的内容:
在这里插入图片描述
参考博客:
QT网络编程之UDP

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-08-16 12:04:52  更:2021-08-16 12:06:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 20:14:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码