组播(UDP)

server/2024/11/15 1:41:46/

1.UDP协议

学习组播就必须先了解UDP。UDP(用户数据报协议,User Datagram Protocol)是一种传输层协议,属于TCP/IP协议族的一部分。它提供了一种简单而高效的方式来在网络上发送数据,但与TCP(传输控制协议)相比,UDP提供的服务具有不同的特征和优势。

UDP的特点:

1.无连接:UDP是一个无连接协议,这意味着在发送数据之前不需要建立连接。这种特性使得UDP在数据传输时不需要建立和维护连接状态,减少了开销和延迟。

2.不可靠:UDP不保证数据报的传递。顺序或者完整性。数据报可能丢失,重复或者乱序到达。UDP不提供重传机制,也不进行错误检查或纠正。

3.低延迟:由于没有建立连接,确认和重传机制,UDP传输数据时的延迟较低,适用于对实时性要求较高的场景。

4.简单:UDP的包头非常简单,仅包含少量的字段,使它的处理和开销比TCP小。

5.数据报服务:UDP以数据报(datagram)形式发送数据,每个数据报都是一个独立的消息,发送端和接收端不需要保持状态信息。

使用场景包括但不限于(在线游戏,视屏会议,以及组播)。

代码示例:使用udp建立客户端与服务端连接

udp_server.cpp

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 12345
#define BUFFER_SIZE 1024int main() {int sockfd;struct sockaddr_in servaddr, cliaddr;char buffer[BUFFER_SIZE];socklen_t len = sizeof(cliaddr);// 创建套接字if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {std::cerr << "Socket creation failed" << std::endl;return 1;}// 填充服务器地址结构memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = INADDR_ANY;servaddr.sin_port = htons(PORT);// 绑定套接字if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {std::cerr << "Bind failed" << std::endl;return 1;}while (true) {// 接收数据int n = recvfrom(sockfd, (char *)buffer, BUFFER_SIZE, 0, (struct sockaddr *)&cliaddr, &len);buffer[n] = '\0';std::cout << "Received message: " << buffer << std::endl;// 回复客户端std::string response = "Message received";sendto(sockfd, response.c_str(), response.length(), 0, (const struct sockaddr *)&cliaddr, len);}close(sockfd);return 0;
}

upd_cliect.cpp

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 12345
#define BUFFER_SIZE 1024int main() {int sockfd;struct sockaddr_in servaddr;char buffer[BUFFER_SIZE];// 创建套接字if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {std::cerr << "Socket creation failed" << std::endl;return 1;}// 填充服务器地址结构memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");servaddr.sin_port = htons(PORT);// 发送数据std::string message = "Hello, UDP server!";sendto(sockfd, message.c_str(), message.length(), 0, (const struct sockaddr *)&servaddr, sizeof(servaddr));// 接收响应int n = recvfrom(sockfd, (char *)buffer, BUFFER_SIZE, 0, NULL, NULL);buffer[n] = '\0';std::cout << "Server response: " << buffer << std::endl;close(sockfd);return 0;
}

运行结果:

2.什么是组播

组播(Multicast)是一种允许数据从源地址发送到多个目标地址的通信方式,它介于单播和广播之间。组播数据报并不是基于IP数据报的目的地址,而是通过RTF(Reverse Path Forwarding)逆向路径转发的方式转发数据包,确保数据只发送到需要接受的组播组成员。组播提高了数据传输效率,减少了骨干网络出现拥塞的可能性,特别适用于一对多的通信场景。

3.组播,单播,广播之间的区别

单播:一对一的通信方式,即一个发送方传输数据到一个接收方,每个数据包都有唯一的目的地址。如果有多个接受者,每个接受者都需要一个独立的副本,会导致带宽的重复消耗。通常使用点对点传输(网页,文件传输和电子邮件)。

广播:一对全(数据被发送到网络中的所有设备)广播地址IPv4(255.255.255.255),广播会消耗整个网络的带宽,所有设备都需要对广播发出的这包数据进行处理,即使有些设备并不需要。通常用于需要再同一网络内的所有设备之间传递信息的场景,如ARP请求(地址解析协议)或者局域网内的服务发现。

4.IPv4组播地址的取值范围

为了使组播源和组播组员进行通信,需要提供网络层组播使用的IP组播地址。IANA(Internet Assigned Numbers Authority)负责管理和分配互联网协议资源的组织将D类地址空间分配给IPv4组播使用,IPv4地址一共32位,D类地址最高4位为1110,地址范围从224.0.0.0到239.255.255.255,。

地址范围

含义

224.0.0.0~224.0.0.255

永久组地址。IANA为路由协议预留的IP地址(也称为保留组地址),用于标识一组特定的网络设备,供路由协议、拓扑查找等使用,不用于组播转发。

224.0.1.0~231.255.255.255

233.0.0.0~238.255.255.255

ASM组播地址,全网范围内有效。

说明:

其中,224.0.1.39和224.0.1.40是保留地址,不建议使用。

232.0.0.0~232.255.255.255

缺省情况下的SSM组播地址,全网范围内有效。

239.0.0.0~239.255.255.255

本地管理组地址,仅在本地管理域内有效。在不同的管理域内重复使用相同的本地管理组地址不会导致冲突。

常见的永久组地址

永久组地址

含义

224.0.0.0

不分配

224.0.0.1

网段内所有主机和路由器(等效于广播地址)

224.0.0.2

所有组播路由器

224.0.0.3

不分配

224.0.0.4

DVMRP(Distance Vector Multicast Routing Protocol,距离矢量组播路由协议)路由器

224.0.0.5

OSPF(Open Shortest Path First,开放最短路径优先)路由器

224.0.0.6

OSPF DR(Designated Router,指定路由器)

224.0.0.7

ST(Shared Tree,共享树)路由器

224.0.0.8

ST主机

224.0.0.9

RIP-2(Routing Information Protocol version 2,路由信息协议版本2)路由器

224.0.0.11

移动代理(Mobile-Agents)

224.0.0.12

DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)服务器/中继代理

224.0.0.13

所有PIM(Protocol Independent Multicast,协议无关组播)路由器

224.0.0.14

RSVP(Resource Reservation Protocol,资源预留协议)封装

224.0.0.15

所有CBT(Core-Based Tree,有核树)路由器

224.0.0.16

指定SBM(Subnetwork Bandwidth Management,子网带宽管理)

224.0.0.17

所有SBM

224.0.0.18

VRRP(Virtual Router Redundancy Protocol,虚拟路由器冗余协议)

224.0.0.22

所有使能IGMPv3(Internet Group Management Protocol, Version 3,因特网组管理协议)的路由器

224.0.0.19 ~ 224.0.0.21

224.0.0.23 ~ 224.0.0.255

未指定

5.IPv4组播MAC地址

以太网传输IPv4单播报文的时候,目的MAC地址使用的是接受者的MAC地址。但是在传输组播数据时,其目的地不再是一个具体的接受者,而是一个成员不确定的组,所以要使用IPv4组播MAC地址,即IPv4组播地址映射到链路层中的地址。

IANA规定,IPv4组播MAC地址的高24位为0x01005e,第25位为0,低23位为IPv4组播地址的低23位。

例如:IPv4组播地址224.1.2.3

转化IPv4的二进制

224.1.2.3 ==> 11100000.00000001.00000010.00000011

提取低23位

00000010.00000011(2.3)

组播MAC地址

MAC地址格式:01:00:5E:xx:xx:xx

结合IPv4的低23位,得到的MAC地址为:01:00:5E:01:02:03

注:IPv4组播地址映射到MAC地址的方式确保了再以太网中,组播数据包能够正确地送到所有订阅了特定组的设备。组播MAC地址的前缀01:00:5E表示该地址用于组播目的。

6.组播协议包解析

组播协议包的解析涉及不同的网络协议层和数据结构,主要包含数据链路层。网络层和传输层。

1.数据链路层

在以太网数据链路层,组播层的目标地址是一个组播MAC地址,通常以01:00:5E:xx:xx:xx的形式表示。数据链路层的组播包包含以下字段:

目的MAC地址:组播MAC地址,例如 01:00:5E:00:00:01
源MAC地址:发送者的MAC地址
以太网类型字段:指示上层协议类型,如IPv4或IPv6.

2.网络层(IPv4)

在网络层,组播包的 IP 地址是在 IPv4 组播地址范围内。IPv4 组播地址的范围是 224.0.0.0239.255.255.255。IPv4 组播数据包的格式如下:

版本:4位,表示IPv4.
头部长度:4位,表示IPV头部长度。
服务类型:8位,表示服务质量
总长度:16位,表示整个数据包的长度。
标识符,标志和片偏移:用于数据包的分片和重组。
生存时间(TTL):8位,控制数据包的生命周期。TTL为1的数据包不会被转发,适用于本地组播。
协议:8位,表示上层协议,如UDP.
源IP地址:发送者的IPv4地址。
目的IP地址:组播地址。

3.传输层(UDP)

在传输层,组播数据通常使用UDP,因为它提供了简单的无连接服务,适合组播流量。UDP头部的格式如下:

源端口:16位,发送方的端口号。
目的端口:16位,接收方的端口号。
长度:16位,UDP数据报的长度(包括头部的数据)。
校验位:16位,用于检查UDP数据包的完整性。

4.应用层

在应用层,组播协议包的解析依赖于具体的应用协议。;例如,应用层可能使用以下协议:

IGMP(Internet Group Management Protocol):用于管理主机加入或离开组播组。IGMP报文在IP头部之后直接跟随,紫萼不使用UDP。
PIM(Protocol IndepenDent MuIticast):用于组播路由的协议。PIM包含在IP数据包中,但其具体的报文格式和解析涉及更多细节。


http://www.ppmy.cn/server/109869.html

相关文章

测试.net core服务项目调用dotNetify-Pulse监控性能的基本用法

微信公众号“DotNet讲堂”的文章《开源 .NET API 实时监控项目》介绍了开源实时日志及性能监控项目dotNetify-Pulse&#xff0c;在项目中引用简单&#xff0c;既能用其自带的监控页面&#xff0c;也支持按需配置监控页面。本文在之前创建的环境检测项目中添加并测试dotNetify-P…

Qt5.15.x之后的版本源码编译安装

在以下网站现在源文件 https://mirrors.tuna.tsinghua.edu.cn/qt/进入网站后选择以下路径 archive/qt/5.15/5.15.8/该路径下 single中是完整qt源码 submodules是各单个模块源码 一、安装基础依赖&#xff0c;此处需要慎重安装&#xff0c;因为分析部分Debian系统和麒麟系统和…

更改网络ip地址时出现错误怎么办

在日常的网络使用中&#xff0c;‌有时我们需要更改IP地址以满足特定的网络需求&#xff0c;‌然而&#xff0c;‌在更改IP地址的过程中&#xff0c;‌可能会遇到各种错误&#xff0c;‌导致无法成功更改或网络连接出现问题。‌‌而更改网络IP地址时出现错误是由于多种原因导致…

Laravel邮件发送功能的实现的方法和技巧?

Laravel邮件发信功能如何配置&#xff1f;怎么使用Laravel发信&#xff1f; 在现代Web开发中&#xff0c;邮件发送功能是不可或缺的一部分。Laravel框架以其优雅的语法和强大的功能&#xff0c;成为了许多开发者的首选。AokSend将深入探讨如何在Laravel中实现邮件发送功能&…

每天学习一个基础算法之二分查找

目录 前言&#xff1a; 1、对二分查找概念的诠释 2、二分查找的使用场景 3、对比顺序查找与二分查找时间复杂度 4、二分查找的实现代码 代码主体&#xff08;以接口函数的形式&#xff09; 实现思路&#xff1a; 测试部分&#xff08;主函数调用&#xff09; 调试结果 前言&…

并发服务器---IO多路复用

单循环服务器&#xff1a;同一时刻只能处理一个客户端任务 并发服务器&#xff1a; 同一时刻&#xff0c;只能处理多个客户端的任务 实现方法&#xff1a;多进程 多线程 IO多路复用 IO多路复用&#xff1a; 1.阻塞io&#xff08;fgets scanf recv getchar read&#x…

【软件测试】软件测试生命周期与Bug

目录 &#x1f4d5; 前言 &#x1f334;软件测试的生命周期 ​编辑&#x1f332;BUG &#x1f6a9; 概念 &#x1f6a9;描述bug的要素 &#x1f6a9;bug的级别 &#x1f6a9;bug的生命周期 &#x1f3c0;先检查自身&#xff0c;是否bug描述不清楚 &#x1f3c0;站在用…

Vue 项目中使用路由鉴权实现网页进度条

概述 在 Web 开发中&#xff0c;用户界面的流畅性和交互性对用户体验至关重要。为了在页面跳转时给用户提供反馈&#xff0c;我们可以利用 NProgress 这样的第三方库来实现一个进度条。本文档将指导您如何在 Vue 项目中结合路由鉴权来实现这一功能。 准备工作 确保您已经安装…