文章目录
UDP
一、windows的UDP编程模型
服务器 | 客户端 |
---|---|
0.协议版本信息 | 0.协议版本信息 |
1.创建socket | 1.创建socket |
2.服务器协议地址簇 | 2.获取服务器协议地址簇 |
3.绑定 | 3.通信:往服务器发数据 |
4.接收客户端数据、顺便获取客户端协议地址簇 | 4.关闭 |
5.关闭 | – |
2、QT的UDP编程模型
服务器 | 客户端 |
---|---|
1.创建socket对象 QUdpSocket | 1.创建socket对象 QUdpSocket |
2.绑定 QUdpSoket::bind | 2.收数据 readDatagram;信号发送者QUdpSocket;信号接收者当前对象this;信号QUdpSocket::readyRead() |
3.收数据 readDatagram;信号发送者QUdpSocket;信号接收者当前对象this;信号QUdpSocket::readyRead() | 3.发送数据 writeDatagram |
4.发送数据 writeDatagram |
QUdpSocket界面
1、添加模式
2、服务器界面
3、客户端界面
3.1添加Qt设计师界面类
选择为widget
改名为client
下一步
完成即可
3.2做client界面
4、将textEditRecv设置为只读
QUdpSocket服务器界面代码
准备工作 0:
0、加入头文件
#include<QUdpSocket>
0、设置窗口标题
服务器:
setWindowTitle("服务器");
0、创建对象:
QUdpSocket *pUdpSocket;
1、创建socket
pUdpSocket=new QUdpSocket(this);
2、绑定
1.需要指定绑定地址,端口号,绑定模式(有默认模式)
2.需要指定端口号,绑定模式(有默认模式)
// 方法一:没有组播 2.绑定
pUdpSocket->bind(8888);
// 方法二:(设置组播)
//pUdpSocket->bind(QHostAddress::AnyIPv4,8888);
3、收数据
//3.接受信号
connect(pUdpSocket,&QUdpSocket::readyRead,[=](){
//3.1接收
char buff[1024]={0};
QHostAddress Ip;
quint16 port;
pUdpSocket->readDatagram(buff,1024,&Ip,&port);//接收数据并保存数据
//3.2显示
//构造器格式化
QString str=QString("ip:%1,port:%2,mage:%3").arg(Ip.toString()).arg(port).arg(buff);
ui->textEditRecv->append(str);
});
4.发送数据
1.右键转到槽函数
2、
//4.发送
void Widget::on_btnSend_clicked()
{
//4.1 获取port和ip
QString ip=ui->lineEditIP->text();
QString port=ui->lineEditPort->text();
QString msg=ui->textEditSend->toPlainText();
pUdpSocket->writeDatagram(msg.toUtf8(),QHostAddress(ip),port.toUInt());
}
QUdpSocket客户端界面代码
0、加入头文件
#include<QUdpSocket>
0、设置窗口标题
服务器:
setWindowTitle("客户端");
0、创建对象:
QUdpSocket *pUdpSocket;
1.创建socket
pUdpSocket=new QUdpSocket(this);
2、收数据
//2.接受信号
connect(pUdpSocket,&QUdpSocket::readyRead,[=](){
//2.1接收
char buff[1024]={0};
QHostAddress Ip;
quint16 port;
pUdpSocket->readDatagram(buff,1024,&Ip,&port);//接收数据并保存数据
//2.2显示
//构造器格式化
QString str=QString("ip:%1,port:%2,mage:%3").arg(Ip.toString()).arg(port).arg(buff);
ui->textEditRecv->append(str);
});
3.发送数据
1.右键转到槽函数
//3.发送
void Widget::on_btnSend_clicked()
{
//4.1 获取port和ip
QString ip=ui->lineEditIP->text();
QString port=ui->lineEditPort->text();
QString msg=ui->textEditSend->toPlainText();
pUdpSocket->writeDatagram(msg.toUtf8(),QHostAddress(ip),port.toUInt());
}
所有代码:
服务器
.h文件
#include <QWidget>
#include<QUdpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_btnSend_clicked();
private:
Ui::Widget *ui;
QUdpSocket *pUdpSocket;
};
#endif // WIDGET_H
cpp文件
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle("服务器");
//1.创建socket
pUdpSocket=new QUdpSocket(this);
// 方法一:没有组播 2.绑定
pUdpSocket->bind(8888);
// 方法二:(设置组播)
//pUdpSocket->bind(QHostAddress::AnyIPv4,8888);
//5.1进组
//pUdpSocket->joinMulticastGroup(QHostAddress("224.0.0.6"));
//pUdpSocket->leaveMulticastGroup(QHostAddress("224.0.0.6")); 退组
//3.接受信号
connect(pUdpSocket,&QUdpSocket::readyRead,[=](){
//3.1接收
char buff[1024]={0};
QHostAddress Ip;
quint16 port;
pUdpSocket->readDatagram(buff,1024,&Ip,&port);//接收数据并保存数据
//3.2显示
//构造器格式化
QString str=QString("ip:%1,port:%2,mage:%3").arg(Ip.toString()).arg(port).arg(buff);
ui->textEditRecv->append(str);
});
Widget::~Widget()
{
delete ui;
}
//4.发送
void Widget::on_btnSend_clicked()
{
//4.1 获取port和ip
QString ip=ui->lineEditIP->text();
QString port=ui->lineEditPort->text();
QString msg=ui->textEditSend->toPlainText();
pUdpSocket->writeDatagram(msg.toUtf8(),QHostAddress(ip),port.toUInt());
}
}
客户端
.h文件
#ifndef CLIENT_H
#define CLIENT_H
#include <QWidget>
#include<QUdpSocket>
namespace Ui {
class client;
}
class client : public QWidget
{
Q_OBJECT
public:
explicit client(QWidget *parent = nullptr);
~client();
private slots:
void on_BtnSend_clicked();
private:
Ui::client *ui;
QUdpSocket *pUdpSocket;
};
#endif // CLIENT_H
cpp文件
#include "client.h"
#include "ui_client.h"
client::client(QWidget *parent) :
QWidget(parent),
ui(new Ui::client)
{
ui->setupUi(this);
setWindowTitle("客户端");
//1.创建socket
pUdpSocket=new QUdpSocket(this);
//2.接受信号
connect(pUdpSocket,&QUdpSocket::readyRead,[=](){
//2.1接收
char buff[1024]={0};
QHostAddress Ip;
quint16 port;
pUdpSocket->readDatagram(buff,1024,&Ip,&port);//接收数据并保存数据
//2.2显示
//构造器格式化
QString str=QString("ip:%1,port:%2,mage:%3").arg(Ip.toString()).arg(port).arg(buff);
ui->textEditRecv->append(str);
});
}
client::~client()
{
delete ui;
}
void client::on_BtnSend_clicked()
{
//3.1 获取port和ip
QString ip=ui->lineEditIP->text();
QString port=ui->lineEditPort->text();
QString msg=ui->textEditSend->toPlainText();
pUdpSocket->writeDatagram(msg.toUtf8(),QHostAddress(ip),port.toUInt());
}
main函数:
#include "widget.h"
#include"client.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
client c;
c.show();
w.show();
return a.exec();
}
点播、广播和组播的区别
点播:一个程序给一个程序发送数据(点对点)
广播:由于Tcp是有连接的,所以不能用来发送广播消息。发送广播消息,必须用到Udp,Udp可以不用建立连接而发送消息。广播消息的目的IP地址是一种特殊IP地址,称为广播地址。广播地址由IP地址网络前缀加上全1主机后缀组成,如:192.168.1.255是192.169.1.0这个网络的广播地址;130.168.255.255是130.168.0.0这个网络的广播地址。向全部为1的IP地址(255.255.255.255)发送消息的话,那么理论上全世界所有的联网的计算机都能收得到了。但实际上不是这样的,一般路由器上设置抛弃这样的包,只在本地网内广播,所以效果和向本地网的广播地址发送消息是一样的。
组播:介于点播和广播之间,优化广播,一组可进可出,组内的可以收到,组外的收不到
D类地址
组播组可以是永久的也可以是临时的。组播组地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。永久组播组中成员的数量都可以是任意的,甚至可以为零。那些没有保留下来供永久组播组使用的ip组播地址,可以被临时组播组利用。
224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;
224.0.1.0~224.0.1.255是公用组播地址,可以用于Internet;
224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;
239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。
设置组播(改变绑定方式,进组):
// 方法一:没有组播 2.绑定
// pUdpSocket->bind(8888);
// 方法二:(设置组播)
pUdpSocket->bind(QHostAddress::AnyIPv4,8888);
//5.1进组
pUdpSocket->joinMulticastGroup(QHostAddress("224.0.0.6"));
pUdpSocket->leaveMulticastGroup(QHostAddress("224.0.0.6")); //退组