udp多播/组播那些事

在这里插入图片描述

多播与组播

多播(multicast)和组播(groupcast)是相同的概念,用于描述在网络中一对多的通信方式。在网络通信中,单播(unicast)是一对一的通信方式,广播(broadcast)是一对所有的通信方式,而多播(或组播)是一对多的通信方式。

多播/组播通信允许一个发送者将数据包同时传输给多个接收者,这些接收者形成一个接收组(receiving group)或多播组(multicast group)。发送者只需发送一次数据包,而不需要为每个接收者单独发送。

只存在于udp

UDP协议支持多播和广播,而TCP协议不直接支持广播和多播。

UDP协议是一种无连接的协议,它允许应用程序通过多播地址或广播地址发送数据包。多播地址是一个预定义的IP地址范围,用于标识多播组,而广播地址则是一个特殊的IP地址,用于向网络中的所有主机发送数据包。

在UDP中,你可以使用特定的套接字选项设置多播地址,并使用sendto()函数发送数据包到多播组。接收端可以通过加入相同的多播组地址,使用recvfrom()函数接收多播数据包。

相比之下,TCP协议是一种面向连接的协议,它提供可靠的、有序的数据传输。TCP协议不直接支持多播和广播功能,因为它是基于点对点通信模型的,只能通过建立一对一的连接进行数据传输。

多播接收端程序

以下是一个使用C语言编写的简单示例,用于接收和发送多播数据包:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>

#define MULTICAST_GROUP "239.0.0.1" // 多播组地址
#define PORT 12345                 // 多播组的端口号
#define MAX_BUFFER_SIZE 1024       // 接收缓冲区大小

int main() {
    int sockfd;
    struct sockaddr_in multicastAddr;
    struct sockaddr_in clientAddr;
    char buffer[MAX_BUFFER_SIZE];

    // 创建UDP套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    // 设置套接字选项,允许接收多播数据
    int enable = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) < 0) {
        perror("setsockopt SO_REUSEADDR failed");
        exit(EXIT_FAILURE);
    }

    // 绑定到本地地址和端口
    memset(&clientAddr, 0, sizeof(clientAddr));
    clientAddr.sin_family = AF_INET;
    clientAddr.sin_addr.s_addr = INADDR_ANY;
    clientAddr.sin_port = htons(PORT);

    if (bind(sockfd, (struct sockaddr *)&clientAddr, sizeof(clientAddr)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 加入多播组
    struct ip_mreq multicastReq;
    multicastReq.imr_multiaddr.s_addr = inet_addr(MULTICAST_GROUP);
    multicastReq.imr_interface.s_addr = htonl(INADDR_ANY);
    if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&multicastReq, sizeof(multicastReq)) < 0) {
        perror("setsockopt IP_ADD_MEMBERSHIP failed");
        exit(EXIT_FAILURE);
    }

    printf("Waiting for multicast messages...\n");

    while (1) {
        // 接收多播数据包
        socklen_t addrLen = sizeof(multicastAddr);
        ssize_t recvLen = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&multicastAddr, &addrLen);
        if (recvLen < 0) {
            perror("recvfrom failed");
            exit(EXIT_FAILURE);
        }

        buffer[recvLen] = '\0';
        printf("Received multicast message: %s\n", buffer);
    }

    // 关闭套接字
    close(sockfd);

    return 0;
}

在该示例中,我们使用socket()函数创建了一个UDP套接字,并使用setsockopt()函数设置了SO_REUSEADDR选项,以便允许套接字重新使用本地地址。然后,我们使用bind()函数将套接字绑定到本地地址和端口。

接下来,我们使用IP_ADD_MEMBERSHIP选项加入多播组,指定了多播组地址和本地网络接口。这样,套接字就可以接收到发送到指定多播组的数据包。

最后,我们使用一个循环来持续接收多播数据包。使用recvfrom()函数从套接字接收数据包,并打印接收到的消息。

请注意,接收端和发送端应该使用相同的多播组地址和端口号以进行通信。

多播发送断程序

以下是一个使用C语言编写的简单多播发送示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>

#define MULTICAST_GROUP "239.0.0.1" // 多播组地址
#define PORT 12345                 // 多播组的端口号

int main() {
    int sockfd;
    struct sockaddr_in multicastAddr;
    char *message = "Hello, Multicast!";

    // 创建UDP套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    // 设置多播组地址和端口号
    memset(&multicastAddr, 0, sizeof(multicastAddr));
    multicastAddr.sin_family = AF_INET;
    multicastAddr.sin_addr.s_addr = inet_addr(MULTICAST_GROUP);
    multicastAddr.sin_port = htons(PORT);

    // 发送多播数据包
    if (sendto(sockfd, message, strlen(message), 0, (struct sockaddr *)&multicastAddr, sizeof(multicastAddr)) < 0) {
        perror("sendto failed");
        exit(EXIT_FAILURE);
    }

    printf("Multicast message sent.\n");

    // 关闭套接字
    close(sockfd);

    return 0;
}

在这个示例中,我们创建了一个UDP套接字,并设置了多播组的地址和端口号。然后,使用sendto()函数将消息发送到多播组的地址。最后,关闭套接字。

注意事项

对于发送多播数据包的示例,不需要显式地绑定本地端口。

在发送端,我们只需创建一个UDP套接字并将数据包发送到多播组的地址。操作系统会自动选择一个本地端口进行发送。

接收端需要绑定本地端口是因为它需要告诉操作系统将接收到的多播数据包发送到哪个端口。

当接收端加入一个多播组时,它需要指定一个本地端口来接收多播数据包。通过将套接字绑定到一个特定的本地端口,操作系统会将接收到的多播数据包传递给该端口上运行的应用程序。

绑定本地端口的步骤通常在接收端的代码中进行,以便接收来自多播组的数据包。在之前提供的多播接收示例中,我们在接收端的代码中使用bind()函数将套接字绑定到本地地址和端口。

简而言之,接收端绑定本地端口是为了告诉操作系统将接收到的多播数据包传递给相应的应用程序,而发送端无需显式地绑定本地端口,操作系统会自动选择一个可用的本地端口进行发送。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/270274.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++】const 关键字

想要正确理解const关键字&#xff0c;只需记住一句话&#xff1a; cosnt关键字优先修饰左边&#xff0c;如果左边每东西&#xff0c;就作用于右边。 const int a; 修饰int a 不能改变 const int *a ; int const *a; 修饰int 指针a指向的地址可以改变&#xff0c;但是地址中…

[pyqt5]QSpinBox相关函数

1.QSpinBox简介 QSpinBox是计数器控件&#xff0c;允许用户输入整数&#xff0c;或者通过上下按键递增或者递减&#xff0c;默认调整范围是0-99&#xff0c;每次变化步数1&#xff0c;用户可以自行修改范围和步数&#xff1b; QSpinBox常用方法如下&#xff1a; QSpinBox信号…

找不到msvcr90.dll文件怎么办?msvcr90.dll丢失如何修复?

在日常使用计算机的过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“msvcr90.dll缺失”。那么&#xff0c;msvcr90.dll到底是什么&#xff1f;为什么会出现丢失的情况&#xff1f;本文将为您详细介绍msvcr90.dll的定义、丢失原因以及提供5种不同的解决…

怎么卸载macOS上的爱思助手如何卸载macOS上的logitech g hub,如何卸载顽固macOS应用

1.在App Store里下载Cleaner One Pro &#xff08;注意&#xff0c;不需要订阅付费&#xff01;&#xff01;&#xff01;白嫖基础功能就完全够了&#xff01;&#xff01;&#xff01;&#xff09; 2.运行软件&#xff0c;在左侧目录中选择“应用程序管理”&#xff0c;然后点…

C++_const常成员作用

介绍 常成员是什么 1.常成员关键词为&#xff1a;const 2.常成员有&#xff1a;常成员变量、常成员函数、常成员对象 常成员有什么用 1.常成员变量&#xff1a;用于在程序中定义不可修改内部成员变量的函数 2.常成员函数&#xff1a;只能够访问成员变量&#xff0c;不可以修改成…

智能优化算法应用:基于斑马算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于斑马算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于斑马算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.斑马算法4.实验参数设定5.算法结果6.参考文献7.MA…

C#教程(五):枚举

1、什么是枚举 枚举&#xff08;Enum&#xff09;是一种用于定义命名常量集合的数据类型。它允许开发人员创建一个命名的整数常量集合&#xff0c;这些常量可以在代码中代表特定的值。 2、示例 以下是一个简单的枚举示例&#xff1a; // 定义一个枚举类型 enum DaysOfWeek …

C++ Qt开发:Charts绘制各类图表详解

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍TreeWidget与QCharts的常用方法及灵活运用。 …

深入探讨多模态模型和计算机视觉

近年来&#xff0c;机器学习领域在从图像识别到自然语言处理的不同问题类型上取得了显着进展。然而&#xff0c;这些模型中的大多数都对来自单一模态的数据进行操作&#xff0c;例如图像、文本或语音。相比之下&#xff0c;现实世界的数据通常来自多种模态&#xff0c;例如图像…

基于[Discretized] Torus的全同态加密指引(2)

前序博客有&#xff1a; 基于[Discretized] Torus的全同态加密指引&#xff08;1&#xff09; 5. 基于已加密数据处理 很显然&#xff0c;TLWE加密方案和TGLWE加密方案均具有加法同态性。[GSW13] Gentry–Sahai–Waters 方法使用matrix product来将TLWE加密方案和TGLWE加密方…

算法导论复习(四)主方法的专题

主方法我们要记住的是什么呢&#xff1f;

matlab附加功能管理器安装蓝牙工具箱

由于最近需要做蓝牙仿真方面的东西&#xff0c;需要用到matlab的蓝牙工具箱&#xff0c;根据官网例子输入&#xff1a; commSupportPackageCheck(BLUETOOTH);检测是否包含该工具箱&#xff0c;结果出现&#xff1a; 点击Add-On-Explorer出现&#xff1a; 网上搜索发现这是因为…

验证码服务使用指南

验证码服务使用指南 1 部署验证码服务 1.1 基础环境 Java 1.8 Maven3.3.9 1.2 安装Redis 参考“Redis安装指南” 1.3 部署验证码服务 1.3.1 下载源码 使用git从远程下载验证码服务代码(开源)。 1.3.2 使用idea打开项目 使用idea打开上一步下载的sailing目录&#xf…

关于Dark Frost 僵尸网络对游戏行业进行DDoS攻击的动态情报

一、基本内容 近期&#xff0c;一种名为Dark Frost 的新型僵尸网络被发现正在对游戏行业发起分布式拒绝服务攻击&#xff08;DDoS)。目标包括游戏公司、游戏服务器托管提供商、在线流媒体甚至和网络信息安全攻击者直接交互的其他游戏社区成员。截至2023年2月&#xff0c;僵尸网…

本地搭建【文档助手】大模型版(LangChain+llama+Streamlit)

概述 本文的文档助手就是&#xff1a;我们上传一个文档&#xff0c;然后在对话框中输入问题&#xff0c;大模型会把问题的答案返回。 安装步骤 先下载代码到本地 LangChain调用llama模型的示例代码&#xff1a;https://github.com/afaqueumer/DocQA&#xff08;代码不是本人…

session 的原理

目录 1&#xff0c;session 的原理如何删除 session1&#xff0c;设置过期时间2&#xff0c;客户端主动通知 2&#xff0c;和 cookie 的区别安全性举例&#xff1a;验证码 3&#xff0c;举例 1&#xff0c;session 的原理 建议先看这篇文章&#xff1a;浏览器 cookie 的原理&a…

C语言操作符if语句好习惯 详解分析操作符(详解4)

各位少年&#xff1a; 前言 还记得我们上一章讲过一个比较抽象的代码&#xff0c;它要比较两次都是真的情况下才能打印&#xff0c;那么很显然这样写代码是有弊端的&#xff1f;哪我们C语言之父丹尼斯.里奇&#xff0c;先介绍一下上次拉掉了if语句的好习惯 好再分享一些操作符…

ref组合式api声明状态

一、ref声明响应式状态&#xff08;支持所有类型&#xff09;&#xff0c;因为内部维护一个refImpl对象{value:***}&#xff0c;,如下图&#xff1a; ref声明的数字、字符、布尔、对象、数组类型的值都存在refImpl 对象的value属性里面 所以&#xff0c;如果要改变ref 声明的变…

国外加固Appdome环境检测与绕过

文章目录 前言第一部分&#xff1a;定位检测逻辑的通用思路1. 通过linux“一切皆文件”思路定位2. 分析现有检测软件猜测可能检测点3. 通过正向开发思路定位4. 通过activity及弹窗定位 第二部分&#xff1a;检测结果展示整体流程1. Jni反射调用doDispath完成广播发送2. NativeB…

实战教学:零食百货商城小程序开发全程指导

随着移动设备的普及和互联网技术的发展&#xff0c;小程序成为越来越多人的选择&#xff0c;特别是在购物方面。开发一个零食百货商城小程序&#xff0c;可以让你在手机上随时随地购买各种零食&#xff0c;方便快捷。本文将为你提供全程指导&#xff0c;让你轻松开发一个成功的…