C语言多服务器多播组网框架

使用技术:

UDP ipv4 禁止本地回环 允许端口复用 超时等待 限制跳点 Echo

功能描述:

任意endpoint可主动发送多播,也可以收到信息后自动多播

前期准备:

开启操作系统多播广播功能,关闭系统防火墙,使用物理路由还需在路由开启广播多播功能

发送端和接收端运行不分先后 可无限复制多个接收端模拟集群

发送端:

#define _GNU_SOURCE
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>#define MULTICAST_GROUP "239.0.0.1"
#define MULTICAST_PORT 55501
//发送端
int main()
{int server_sockfd;struct sockaddr_in server_sockaddr, multi_sockaddr, recv_sockaddr;memset(&server_sockaddr, 0, sizeof(server_sockaddr));memset(&multi_sockaddr, 0, sizeof(multi_sockaddr));memset(&recv_sockaddr, 0, sizeof(recv_sockaddr));socklen_t multi_sockaddr_len = sizeof(multi_sockaddr);socklen_t server_sockaddr_len = sizeof(server_sockaddr);socklen_t recv_sockaddr_len = sizeof(recv_sockaddr);ssize_t send_bytes, recv_bytes;char send_buf[1024] = "multicast from ubuntu";char recv_buf[1024] = {0};char recv_sockaddr_ip[INET_ADDRSTRLEN] = {0};// 用于加入多播网络struct ip_mreq mreq = {0};// 用于超时等待struct timeval tv = {0};tv.tv_sec = 1;tv.tv_usec = 0;// ipv4 udpserver_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (server_sockfd == -1){perror("socket");}// 地址端口复用int optval = 1;setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));// 超时等待setsockopt(server_sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));// 限制跳点uint8_t ttl = 1;setsockopt(server_sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));// 禁止本地回环uint8_t loop = 0;setsockopt(server_sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));// 绑定接收端口,与多播端口一致,监听任意地址server_sockaddr.sin_family = AF_INET;server_sockaddr.sin_port = htons(MULTICAST_PORT);server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);if ((bind(server_sockfd, (struct sockaddr *)&server_sockaddr, server_sockaddr_len)) == -1){perror("bind");}// 加入多播组inet_pton(AF_INET, MULTICAST_GROUP, &mreq.imr_multiaddr.s_addr);mreq.imr_interface.s_addr = htonl(INADDR_ANY);setsockopt(server_sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));// 设置发送地址为多播组multi_sockaddr.sin_family = AF_INET;multi_sockaddr.sin_port = htons(MULTICAST_PORT);inet_pton(AF_INET, MULTICAST_GROUP, &multi_sockaddr.sin_addr.s_addr);while (1){sleep(1);send_bytes = sendto(server_sockfd, send_buf, strlen(send_buf),0, (struct sockaddr *)&multi_sockaddr, multi_sockaddr_len);if (send_bytes == -1){perror("sendto");}recv_bytes = recvfrom(server_sockfd, recv_buf, sizeof(recv_buf),0, (struct sockaddr *)&recv_sockaddr, &recv_sockaddr_len);if (recv_bytes == -1){perror("recvfrom");}inet_ntop(AF_INET, &recv_sockaddr.sin_addr, recv_sockaddr_ip, sizeof(recv_sockaddr_ip));// 收到消息则打印日志if (recv_bytes > 0){printf("INET_ADDR : %s PORT : %d Message : %s\n", recv_sockaddr_ip, ntohs(recv_sockaddr.sin_port), recv_buf);memset(recv_buf, 0, sizeof(recv_buf));memset(&recv_sockaddr, 0, sizeof(recv_sockaddr));}}close(server_sockfd);return 0;
}

接收端:

#define _GNU_SOURCE
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>#define MULTICAST_GROUP "239.0.0.1"
#define MULTICAST_PORT 55501
//接收端
int main()
{int server_sockfd;struct sockaddr_in server_sockaddr, multi_sockaddr, recv_sockaddr;memset(&server_sockaddr, 0, sizeof(server_sockaddr));memset(&multi_sockaddr, 0, sizeof(multi_sockaddr));memset(&recv_sockaddr, 0, sizeof(recv_sockaddr));socklen_t multi_sockaddr_len = sizeof(multi_sockaddr);socklen_t server_sockaddr_len = sizeof(server_sockaddr);socklen_t recv_sockaddr_len = sizeof(recv_sockaddr);ssize_t send_bytes, recv_bytes;char send_buf[1024] = "multicast from kali";char recv_buf[1024] = {0};char recv_sockaddr_ip[INET_ADDRSTRLEN] = {0};struct ip_mreq mreq = {0};server_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (server_sockfd == -1){perror("socket");}// 禁止本地回环uint8_t loop = 0;setsockopt(server_sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));// 允许端口复用int optval = 1;setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));// 绑定地址为监听任意,绑定监听端口为多播端口server_sockaddr.sin_family = AF_INET;server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);server_sockaddr.sin_port = htons(MULTICAST_PORT);if ((bind(server_sockfd, (struct sockaddr *)&server_sockaddr, server_sockaddr_len)) == -1){perror("bind");}// 加入多播组mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_GROUP);mreq.imr_interface.s_addr = htonl(INADDR_ANY);setsockopt(server_sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));// 向多播组发送消息用multi_sockaddr.sin_family = AF_INET;multi_sockaddr.sin_port = htons(MULTICAST_PORT);inet_pton(AF_INET, MULTICAST_GROUP, &multi_sockaddr.sin_addr.s_addr);while (1){recv_bytes = recvfrom(server_sockfd, recv_buf, sizeof(recv_buf),0, (struct sockaddr *)&recv_sockaddr, &recv_sockaddr_len);if (recv_bytes == -1){perror("recvfrom");}inet_ntop(AF_INET, &recv_sockaddr.sin_addr, recv_sockaddr_ip, sizeof(recv_sockaddr_ip));// 如果收到了消息就打印if (recv_bytes > 0){printf("INET_ADDR : %s PORT : %d Message : %s\n", recv_sockaddr_ip, ntohs(recv_sockaddr.sin_port), recv_buf);memset(recv_buf, 0, sizeof(recv_buf));memset(&recv_sockaddr, 0, sizeof(recv_sockaddr));}sleep(1);// echo一条消息,也可主动发起send_bytes = sendto(server_sockfd, send_buf, strlen(send_buf),0, (struct sockaddr *)&multi_sockaddr, multi_sockaddr_len);if (send_bytes == -1){perror("sendto");}}close(server_sockfd);return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

慧天【HTWATER】:水文水动力模型的革命性工具,城市内涝的精准解决方案

城市内涝水文水动力模型介绍 在城市排水防涝规划过程中&#xff0c;水文水动力耦合模型已经成为一种不可或缺的分析工具。在模型建立、城市内涝风险评估、排水系统性能诊断以及海绵城市规划等方面&#xff0c;内涝耦合模型提供了相应的模拟及分析工具&#xff1a; 1.1丰富的数…

前端学习<二>CSS基础——09-CSS案例讲解:博雅互动

前言 CSS已经学了一些基础内容了&#xff0c;我们来讲解一个小案例吧。以博雅互动的官网首页举例。 版心 首页的版心如下&#xff1a; 这里我们要普及一个概念&#xff0c;叫“版心”。版心是页面中主要内容所在的区域。 比如说&#xff0c;网站左上角的logo&#xff0c;设计…

Flutter 开发学习笔记(0):环境配置

文章目录 前言开发需求环境配置运行出现问题我运行也是解决了很久的问题镜像源设置为清华的镜像源&#xff08;不知道有没有影响&#xff09;使用JDK21&#xff0c;JDK版本不能低于JDK11手动下载flutter 对应的gradle 运行成功&#xff01; 前言 我最近一直在用Uniapp写代码&a…

vmware,linux,centos7,NAT模式下的网络配置

centos7的NAT网络配置 NAT模式说明虚拟机网络配置工具本机配置net8网络&#xff08;NAT的网域&#xff09;本机的IP配置(用于net8局域网内解析主机IP和域名对应关系使用)&#xff08;可选&#xff09;虚拟机内的网络配置虚拟机ping不通www.baidu.com的情况下虚拟机ping可以ping…

ARM64架构栈帧以及帧指针FP

文章目录 前言一、arm64架构寄存器简介1.1 异常等级1.2 通用寄存器1.3 ARM64架构ABI 二、ARM64架构函数调用标准2.1 AArch64过程调用标准简介2.2 通用寄存器中的参数 三、demo分析3.1 main函数3.2 funb3.3 funa 四、栈帧总结五、demo演示参考资料 前言 这篇文章描述了 x86_64架…

智过网:一建36岁好不好找工作?能干什么?

在职业发展的道路上&#xff0c;许多人在不同的年龄阶段都会面临不同的挑战和机遇。对于36岁这一年龄阶段的人来说&#xff0c;如果已经通过了国家一级建造师&#xff08;一建&#xff09;的考试&#xff0c;那么他们在找工作方面会有怎样的前景呢&#xff1f;又能从事哪些职业…

气象预测新篇章:Python人工智能的变革力量

Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;在数据处理、科学计算、数学建模、数据挖掘和数据可视化方面具备优异的性能&#xff0c;这些优势使得Python在气象、海洋、地理、气候、水文和生态等地学领域的科研和工程项目中得到广泛应用。可以…

20.变量的使用方式和注意事项

文章目录 一、变量的用法二、变量的注意事项三、总结 一、变量的用法 代码示例 public static void main(String[] args) {//1.基本用法// 定义变量&#xff0c;再进行输出int a 10;System.out.println(a);// 10System.out.println(a);// 10//2.变量参与计算int b 30;int c …

代码随想录学习Day 21

回溯算法理论基础 回溯法又叫回溯搜索法。回溯是递归的副产品&#xff0c;有递归就会有回溯&#xff0c;回溯操作一般出现在递归函数的下面。回溯函数 递归函数。回溯法的本质是穷举。 回溯法解决的问题&#xff1a; 组合问题&#xff1a;N个数里面按一定规则找出k个数的集…

【超图 SuperMap3D】【基础API使用示例】51、超图SuperMap3D - 绘制圆|椭圆形面标注并将视角定位过去

前言 引擎下载地址&#xff1a;[添加链接描述](http://support.supermap.com.cn/DownloadCenter/DownloadPage.aspx?id2524) 绘制圆形或者椭圆形效果 核心代码 entity viewer.entities.add({// 圆中心点position: { x: -1405746.5243351874, y: 4988274.8462937465, z: 370…

小狐狸JSON-RPC:钱包连接,断开连接,监听地址改变

detect-metamask 创建连接&#xff0c;并监听钱包切换 一、连接钱包&#xff0c;切换地址&#xff08;监听地址切换&#xff09;&#xff0c;断开连接 使用npm安装 metamask/detect-provider在您的项目目录中&#xff1a; npm i metamask/detect-providerimport detectEthereu…

vue2的孙子传值给爷爷,爷爷传值给孙子

孙---->爷 在爷爷组件&#xff0c;给父亲组件绑定一个方法 定义一个方法用来接受传来的值 在父亲组件中 给孙子组件绑定v-on“$listeners” 在孙子组件 在特定掉件触发下&#xff0c;将值穿过去&#xff0c;注意&#xff1a;这里的this.$emit的名字要跟爷爷绑定的一…

R语言赋值符号<-、=、->、<<-、->>的使用与区别

R语言的赋值符号有&#xff1c;-、、-&#xff1e;、&#xff1c;&#xff1c;-、-&#xff1e;&#xff1e;六种&#xff0c;它们的使用与区别如下: <-’&#xff1a;最常用的赋值符号。它将右侧表达式的值赋给左侧的变量&#xff0c;像一个向左的箭头。例如&#xff0c;x …

【大数据运维】minio 常见shell操作

文章目录 1. 安装2. 入门操作3. 命令帮助 1. 安装 下载 https://dl.min.io/client/mc/release/linux-amd64/ 赋权与使用 cp mc /usr/bin && chmod x /usr/bin/mc ./mc --help 2. 入门操作 # 添加minio到mc mc config host add minio_alias_name endpoint_adress …

超市收银系统-亿发智能收银,引领线上线下一体化新零售管理

社交新零售的传播核心在于移动互联网。从信任关系的角度来看&#xff0c;移动互联网为用户之间搭建了沟通的桥梁&#xff0c;促进了人们之间更频繁的交流&#xff0c;从而建立了信任关系。从场景的角度来看&#xff0c;移动互联网使得用户之间的沟通更加多样化&#xff0c;包括…

Tomcat项目创建 以及 在IDEA当中集成Tomcat

一: 有关Tomcat的WEB项目创建 TOMCAT项目的创建有两种方式, 第一种是利用骨架进行创建, 第二种是利用填补进行相应的创建, 不适用骨架进行创建 ,在这里主要聊第二种 (使用IDEA版本为2023) 1. 创建MAVEN项目, 非骨架形式 2.在相应的pom文件当中设置打包方式 为 war包的打包形…

基于Java在线考试系统系统设计与实现(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

HarmonyOS 应用开发之任务(Mission)与启动模式

如前文所述&#xff0c;一个UIAbility实例对应一个任务。UIAbility实例个数与UIAbility配置的启动模式有关。在FA模型下&#xff0c;通过config.json配置文件中的“launchType”属性配置&#xff1b;在Stage模型下&#xff0c;通过 module.json5配置文件 中的“launchType”属性…

兆欧表揭秘:到底是摇表还是电器?

兆欧表&#xff0c;又称摇表&#xff0c;是一种用于测量电气设备、电缆、电机绕组等绝缘电阻的测试工具。虽然现代兆欧表采用电动型和电池供电等多种形式&#xff0c;但其基本功能和用途保持一致。早期的兆欧表多采用手动机械式设计&#xff0c;通过手柄摇动发电来提供所需的高…

OpenCV4.9关于矩阵上的掩码操作

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇:如何使用OpenCV扫描图像、查找表和时间测量 下一篇:OpenCV4.9的是如何进行图像操作 引言&#xff1a; 矩阵上的掩码操作非常简单。这个想法是&#xff0c;我们根据掩码矩阵&#xff08…