UDP多对多组播通信

广播和多播仅应用于UDP。TCP是一个面向连接的协议,TCP一定是点对点的,一点是两个主机来建立连接的,TCP肯定是单播。只有UDP才会使用广播和组播。

如下示例实现一个UDP多对多的组播通信,进程中有收、发两个线程,分别表示往组播发送、接收数据。

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>

// 组播地址必须是D类地址,224.0.0.0~239.255.255.255
#define GROUP_IP "239.0.0.1"
#define GROUP_PORT 8888
#define MAX_MESSAGE 128

void *sender(void *arg) {
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        printf("Sender alloc socket failed! %s", strerror(errno));
        pthread_exit(NULL);
    }
    
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(GROUP_IP);
    addr.sin_port = htons(GROUP_PORT);
    
    while(1) {
        char message[MAX_MESSAGE];
        printf("Enter message to send: ");
        fgets(message, MAX_MESSAGE, stdin);
        sendto(sockfd, message, strlen(message), 0, (struct sockaddr *)&addr, sizeof(addr));
    }
    
    close(sockfd);
    pthread_exit(NULL);
}

void *receiver(void *arg) {
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        printf("Receiver alloc socket failed! %s", strerror(errno));
        pthread_exit(NULL);
    }
    
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(GROUP_IP);
    addr.sin_port = htons(GROUP_PORT);

    struct ip_mreq mreq;
    mreq.imr_multiaddr.s_addr = inet_addr(GROUP_IP);
    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
    
    /* 加入组播 */
    int ret = setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
    if (ret < 0) {
        printf("IP_ADD_MEMBERSHIP failed! %s", strerror(errno));
        pthread_exit(NULL);
    }

    /* 设置端口复用,多个进程监听同一端口 */
    ret =  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &mreq, sizeof(mreq));
    if (ret < 0) {
        printf("SO_REUSEADDR failed! %s", strerror(errno));
        pthread_exit(NULL);
    }

    ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
    if (ret < 0) {
        printf("Bind failed! %s", strerror(errno));
        pthread_exit(NULL);
    }

    char message[MAX_MESSAGE];
    struct sockaddr_in sender_addr;
    socklen_t sender_len = sizeof(sender_addr);
    
    while(1) {
        recvfrom(sockfd, message, MAX_MESSAGE, 0, (struct sockaddr *)&sender_addr, &sender_len);
        printf("Received message from %s:%d - %s\n", inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port), message);
    }
    
    close(sockfd);
    pthread_exit(NULL);
}

int main() {
    pthread_t threadA, threadB;
    
    pthread_create(&threadA, NULL, sender, NULL);
    pthread_create(&threadB, NULL, receiver, NULL);
    
    pthread_join(threadA, NULL);
    pthread_join(threadB, NULL);
    
    return 0;
}

运行结果如下:

在这里插入图片描述

使用任意节点发送消息,其它的节点都能收到。

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

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

相关文章

React渲染流程

在 React 渲染分为两个阶段&#xff0c;Render 和 Commit&#xff0c;Render 是修改 React 组件的状态&#xff0c;把需要更新的组件标记为待更新&#xff0c;在 Commit 阶段将待更新的组件进行渲染并最终更新到浏览器的 Dom 树中。 Render 阶段是可以并执行操作的&#xff0c…

【MySQL】表的增删改查 | CRUD | 新增 | 查询 | 修改 | 删除 | 数据库约束

文章目录 表的增删改查一、CRUD1.新增&#xff08;Create&#xff09;1.插入多行2.指定列多行插入3.插入datetime类型4.插入当前时间5.插入查询的结果 2.查询&#xff08;Retrieve&#xff09;1.全列查询 *2.指定列查询3.查询字段为表达式4.指定别名 as5.去重 distinct6.排序 o…

Excel提取某一列的唯一值

点击【筛选】&#xff08;【高级筛选】&#xff09;&#xff0c;参数里&#xff1a; 列表区域&#xff1a;为需要选择唯一值的那一列复制到&#xff1a;生成唯一值的目标区域 据说新版本的excel有了unique()函数&#xff0c;可以很快捷的选择某一列的唯一值&#xff0c;但是博…

大模型时代下的先行者:景联文科技引领数据标注新时代

在大模型时代&#xff0c;数据标注不再是简单的分类标注&#xff0c;而是一项融合了技术革新、专业技能、法律合规和精细化管理的综合性任务&#xff0c;对推动AI技术的发展和落地应用具有重要意义。 景联文科技作为AI基础行业的数据供应商&#xff0c;可协助人工智能企业解决整…

记录一下自己的宏碁暗影骑士电脑的属性

TOC 前言 没有前言。 参考博文 怎么查自己电脑服务器信息吗,如何查看自己电脑的服务器 一、cmd 看到服务器型号 wmic csproduct get name查询CPU个数 按照博主的方法&#xff0c;我出现了报错。 在 Windows 上&#xff0c;您可以通过 PowerShell 来执行类似的操作。您可以…

测缝计测量的是实际缝宽吗?

在土木工程中&#xff0c;测缝计作为一种重要的监测工具&#xff0c;广泛应用于桥梁、隧道、大坝等大型结构中&#xff0c;用以测量和监控结构接缝或裂缝的实际宽度变化。然而&#xff0c;有些人可能会产生疑问&#xff1a;测缝计测量的是实际缝宽吗?本文将对这一问题进行深入…

QCheckBox样式表qss实现状态切换显示不同图标(含第三状态:半选状态)

QCheckBox实际上支持三种状态&#xff1a;选中、未选中、半选 本文介绍如何使用qss实现这三种状态的样式&#xff0c;设置各状态的勾选框图标 需要调用setTristate(true)函数开启第三状态&#xff0c;默认是只有两种状态的。 网上百度很容易找到选中和未选中的qss样式&#…

基于Nios-II实现流水灯

文章目录 一、新建项目1、选择芯片2、Qsys设计2.1、点击Platform Designer2.2配置软核2.3其他设置 3、Quartus设计3.1添加原理图3.2添加qip文件3.3其他设置3.4驱动设置 4、Nios-II Eslipse设计参考 一、新建项目 使用的Quartus 18.0及以上版本 1、选择芯片 2、Qsys设计 2.1、点…

MT3037 新月轩就餐

思路&#xff1a; 此题每道菜的价钱相同&#xff0c;想最小化付的钱即求最小区间长度可以满足“品尝到所有名厨手艺”。 使用双端队列存储元素&#xff0c;队尾不断向后遍历&#xff1a;头->尾 如果队头队尾&#xff0c;则队头往右移一格&#xff0c;直到区间不同元素数m…

自学C语言能达到什么境界呢?

C 语言是一门广泛应用于系统软件、嵌入式系统、游戏开发等领域的编程语言。那么&#xff0c;通过自学 C 语言&#xff0c;能够达到什么样的境界呢&#xff1f; 就像学习小提琴一样&#xff0c;仅凭自学也可以达到一定的水平&#xff0c;能够自娱自乐&#xff0c;在亲友聚会时表…

xxljob分片广播+多线程实现高效定时同步elasticsearch索引库

需求&#xff1a;为了利用elasticsearch实现高效搜索&#xff0c;需要将mysql中的数据查出来&#xff0c;再定时同步到es里&#xff0c;同时在同步过程中通过分片广播多线程提高同步数据的效率。 1. 添加映射 使用kibana添加映射 PUT /app_info_article {"mappings&quo…

AutoNeRF:Training Implicit Scene Representations with Autonomous Agents

论文概述 《AutoNeRF》是由Pierre Marza等人撰写的一篇研究论文&#xff0c;旨在通过自主智能体收集数据来训练隐式场景表示&#xff08;如神经辐射场&#xff0c;NeRF&#xff09;。传统的NeRF训练通常需要人为的数据收集&#xff0c;而AutoNeRF则提出了一种使用自主智能体高效…

知识图谱必须要图数据库嘛?

在 ZH上又看到一个问题&#xff0c;觉得挺有意思&#xff0c;小聊一二。 “知识图谱必须要图数据库吗&#xff1f;” ——使用非关系型数据库&#xff0c;关系型数据库&#xff0c;在计算图的一些特征上&#xff0c;通过优化算法是否能达到使用图数据库接近的计算速度呢&#x…

【数据结构】栈的实现(链式栈)

文章目录 栈的实现&#xff08;链式栈&#xff09;栈的定义初始化栈进栈判断是否为空栈出栈销毁栈获取栈顶元素获取栈的长度栈的打印 完整代码&#xff08;包括测试代码&#xff09;Stack.hStack.ctest.c 栈的实现&#xff08;链式栈&#xff09; 首先新建一个工程&#xff1a…

SHAP - 解释机器学习

文章目录 一、关于 SHAP二、安装三、树集成示例&#xff08;XGBoost/LightGBM/CatBoost/scikit-learn/pyspark 模型&#xff09;四、自然语言示例&#xff08;transformers&#xff09;五、使用 DeepExplainer 的深度学习示例&#xff08;TensorFlow/Keras 模型&#xff09;六、…

如何利用R包进行主成分分析和可视化

一. 使用R包“FactoMineR”进行主成分分析&#xff08;PCA&#xff09; 基本步骤如下&#xff1a; 安装和加载包&#xff1a;如果尚未安装&#xff0c;首先安装“FactoMineR”包&#xff0c;然后加载它&#xff1a; install.packages("FactoMineR")library(FactoM…

2024年5月面试知识点梳理

2024年5月面试知识点梳理 资料来源Java基础泛型基本概念常见问题 字符串注解异常反射SPI机制Java集合CollectionMap 并发基础基础理论线程Java 中的锁乐观锁与悲观锁自旋锁与非自旋锁公平锁与非公平锁 并发关键字 - synchronized并发集合Lock核心类并发集合核心类原子类核心类线…

ARM机密计算组件

安全之安全(security)博客目录导读 目录 ​一、硬件架构 1、RME 二、软件和固件架构 1、RMM 2、其他固件标准&#xff08;例如PSCI&#xff09; 三、开源实现 1、TF-A 2、Veraison 3、工具链 四、动态TrustZone技术 Arm机密计算架构(Arm CCA)引入了一系列硬件和软件…

vue网页端控制台展示独有标记

效果展示 实现步骤 1. 新建js文件 定义一个类 用于提供控制台打印日志显示样式的方法 src\libs\util.log.js class Logger {// 定义静态方法static typeColor(type "default") {let color "";switch (type) {case "default":color "#3…