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.0
到 239.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数据包中,但其具体的报文格式和解析涉及更多细节。