UDP通信过程 + udp文本发送 + udp多播组播
linux下的udp 通信过程:
![d6ab0f4f45dda9602176a9aefc49e31c.png](https://i-blog.csdnimg.cn/blog_migrate/844ac86e3c3af76122a690e4bdeab1a4.png)
Qt下的UDP 通信过程:
![9a76f15b76bca6f6427048cae5c46b78.png](https://i-blog.csdnimg.cn/blog_migrate/7b061c49bbbb65e70a1f5b8e89a8d8ac.jpeg)
组播地址分类(组播地址一定要用D类):
![d2e0716980cdcb94ae33970b0a3f1e5a.png](https://i-blog.csdnimg.cn/blog_migrate/7f1b0364a87bce4e6a85b78208926e95.png)
工程目录:
![353de5a366b6dcd494476d26f29d4075.png](https://i-blog.csdnimg.cn/blog_migrate/9fd385aecdba22398061188722c5682d.png)
#-------------------------------------------------
#
# Project created by QtCreator 2019-07-08T09:05:20
#
#-------------------------------------------------
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Udp
TEMPLATE = app
SOURCES += main.cpp
widget.cpp
HEADERS += widget.h
FORMS += widget.ui
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QUdpSocket>//UDP套接字
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
//之前用的都是lambda表达式,这次就用自定义的槽函数,来温习以下以前所学的内容;
void dealMsg();//槽函数,处理对方发过来的数据(槽函数的形式与信号保持一致,没有参数)
private slots:
void on_buttonSend_clicked();
private:
Ui::Widget *ui;
QUdpSocket *udpSocket;//UDP套接字
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QHostAddress>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//分配空间,指定父对象
udpSocket = new QUdpSocket(this);
//绑定
udpSocket->bind(8888);
//组播的绑定
/*udpSocket->bind(QHostAddress::AnyIPv4,8888);
*/
/*总是广播的话,容易造成网络拥堵,造成丢包的现象较多,所以出现了组播(类似建立qq群)
* 加入某个组播
* 组播地址是D类地址
* 事实上这么写udpSocket->joinMulticastGroup(QHostAddress("224.0.0.2"));
* 依然不对的,会出现cannot bind to QHostAddress::Any 这样一句话,这是因为电脑上本身既有Ipv4又有ipv6,
* 此时就不能使用udpSocket->bind(8888);进行绑定,这样绑定是绑定任何的ip。
* 而应该使用udpSocket->bind(QHostAddress::AnyIPv4,8888);
*
*/
udpSocket->joinMulticastGroup(QHostAddress("224.0.0.2"));
// udpSocket->leaveMulticastGroup(QHostAddress("224.0.0.2"));//退出组播
setWindowTitle("服务器端口:8888");
//当对方成功发送数据过来
//自动触发readyRead()
//之前用的都是lambda表达式,这次就用自定义的槽函数,来温习以下以前所学的内容;
connect(udpSocket,&QUdpSocket::readyRead,this,&Widget::dealMsg);
}
void Widget::dealMsg()
{
//读取对方发送的内容
char buf[1024] = {0};
QHostAddress cliAddr;//对方地址
quint16 port;//对方端口号
qint64 len = udpSocket->readDatagram(buf,sizeof(buf),&cliAddr,&port);
if (len > 0)
{
//格式化 输出的形式如:[111.111.111.111:8888] aaaa
QString str = QString("[%1 : %2] %3").arg(cliAddr.toString()).arg(port).arg(buf);
//给编辑区设置内容
ui->textEdit->setText(str);
}
}
Widget::~Widget()
{
delete ui;
}
//发送按钮(转到槽)
void Widget::on_buttonSend_clicked()
{
//先获取对方的IP和端口
QString ip = ui ->lineEditIp->text();
qint16 port = ui->lineEditPort->text().toInt();
//获取编辑区内容
QString str = ui->textEdit->toPlainText();
//给指定的IP发送数据
udpSocket->writeDatagram(str.toUtf8(),QHostAddress(ip),port);
}
ui:
![d74ea77e759f10bb6b940dbf04706f97.png](https://i-blog.csdnimg.cn/blog_migrate/8fa6327be00d5c2751768da38a1516eb.jpeg)
![5cd36661591c31ecaf7208cb2ce8c00f.png](https://i-blog.csdnimg.cn/blog_migrate/454f3e2d8c0fd642c3946a0128346499.jpeg)
![6dbc8657907e9179e7f96fb4a7f828cd.png](https://i-blog.csdnimg.cn/blog_migrate/0887ba8458dcbb3d8643c941d1f0fd9f.png)