udp协议实现组播功能

news/2025/3/20 6:40:54/文章来源:https://www.cnblogs.com/bell-c/p/18231531

/****************************************************************************************************************************************   file name:multicast.c*   author   :momolyl@126.com*   date     :2024/06/04*   brief    :小组实现,小组中的每位成员都需要设计程序,要求程序可以加入到一个多播组中并等待服务器发送数据包,* 			   并且程序还需要具有发送功能,如果收到数据包则把消息内容输出到终端,* 			   消息内容格式 [消息来源IP  消息时间 ] : 消息内容*   note     :运行多播可执行文件   ./multicast  服务器端口  多播组地址**   CopyRight (c) 2024    momolyl@126.com    All Right Reseverd* ***********************************************************************************************************************************/
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <unistd.h>
#include <time.h>// 接受消息线程
void *pthreadrecv_task(void *argv)
{// 1.创建UDP套接字int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);if (udp_socket == -1){fprintf(stderr, "udp socket error,errno:%d,%s\n", errno, strerror(errno));exit(1);}// 2.需要先绑定服务器的端口和地址struct sockaddr_in host_addr;host_addr.sin_family = AF_INET;				   // 协议族,是固定的host_addr.sin_port = htons(atoi("9999"));	   // 目标端口,必须转换为网络字节序host_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 目标地址 "192.168.64.xxx"  已经转换为网络字节序  INADDR_ANYbind(udp_socket, (struct sockaddr *)&host_addr, sizeof(host_addr));// 3.调用recvfrom等待接收数据,并且接收客户端的网络信息char buf[128] = {0};struct sockaddr_in client;socklen_t client_len = sizeof(client);// 2.获取当前系统时间const char *weekday[] = {"日", " 一", " 二", "三", "四", "五", "六"};char timebuf[128] = {0};time_t CurrentTime;while (1){time(&CurrentTime);struct tm *time = localtime(&CurrentTime);sprintf(timebuf, "%d年 %02d月 %02d日 星期%s %02d:%02d:%02d", time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,weekday[time->tm_wday], time->tm_hour, time->tm_min, time->tm_sec);recvfrom(udp_socket, buf, sizeof(buf), 0, (struct sockaddr *)&client, &client_len); // 默认会阻塞printf("[消息来源:%s 当前时间:%s]:%s\n", inet_ntoa(client.sin_addr), timebuf, buf);bzero(buf, sizeof(buf));bzero(timebuf, sizeof(timebuf));}
}int main(int argc, char *argv[])
{char timebuf[128] = {0};pthread_t pthreadrecv;pthread_create(&pthreadrecv, NULL, pthreadrecv_task, NULL);// 检查参数有效性(多播组地址:224.6.6.6 端口:9999)if (argc != 3){fprintf(stderr, "argument is invaild ,errno:%d,%s\n", errno, strerror(errno));exit(1);}// 1.创建UDP套接字int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);if (udp_socket == -1){fprintf(stderr, "udp socket error,errno:%d,%s\n", errno, strerror(errno));exit(1);}// 加入多播组struct ip_mreqn mutipcast;struct in_addr imr_multiaddr;mutipcast.imr_multiaddr.s_addr = inet_addr("224.6.6.6");mutipcast.imr_address.s_addr = inet_addr("192.168.64.230");mutipcast.imr_ifindex = 0;setsockopt(udp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mutipcast, sizeof(mutipcast));// 设置广播属性int optval = 1;setsockopt(udp_socket, SOL_SOCKET, SO_BROADCAST, (void *)&optval, 4);// 2.向目标主机发送消息,需要设置目标端口和目标地址char buf[128] = "HELLO WORLD";struct sockaddr_in dest_addr;dest_addr.sin_family = AF_INET;					// 协议族,是固定的dest_addr.sin_port = htons(atoi(argv[1]));		// 服务器端口,必须转换为网络字节序dest_addr.sin_addr.s_addr = inet_addr(argv[2]); // 服务器地址 "192.168.64.xxx"while (1){// 3.向多播组发送内容sendto(udp_socket, buf, strlen(buf), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));sleep(5);}return 0;
}

运行结果:
image

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

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

相关文章

Archlinux安装教程

先放张图:准备工作 1、进入 Live 环境后关闭 reflector systemctl stop reflector 2、使用iwctl联网 3、timedatectl 修改时区 timedatectl set-timezone Asia/Shanghai 4、date验证时间 fdisk -l 查看硬盘和分区情况 cfdisk <硬盘编号> 修改分区 如:cfdisk /dev/sda…

若依创建表格

若依创建表格 一、首先在数据库中创建表格 1、新建Mysql数据库2、将字符集与排序规则改成如图所示,数据库名字自己取3、新建表4、在表中新建字段5、创建表,前5个根据规范是必须要有的6、保存表,自己取表名二、启动项目 1、将项目中的sql数据库拖到数据库中2、将配置文件中的…

JQL相关写法整理

一。子节点的field写法:const res3 = await db.collection(res1, res2).field(_id._value as value, name as text, _id["ws-config-brand"] as children).get()因为 ws-config-brand 含有特殊字符 - ,所以需要用 [""] 括起来 比如,想实现分类与品牌联动…

路由器动态分配(rip和ospf)

实验二 路由器动态路由的配置方法一、实验目的: 1.理解动态路由的工作原理; 2. 学习并掌握动态路由协议RIP的配置; 3.学习并掌握动态路由协议OSPF的配置; 4.进一步学习路由器的配置命令。 二、实验原理: RIP:Routing Information Protocol,路由信息协议,是应用较早…

1500PLC通过232自由口转profinet网关接ABB扫码枪通讯方案

在不动其他设备和程序的情况下只需要添加一台232自由口转profinet网关(XD-PNR100),232自由口转profinet网关集成了网口和串口,支持扫码枪的自由协议以及接口转换。232自由口转Profinet网关将传统的232自由口协议转换为现代化的Profinet协议,成功接入到1500PLC上,实现无缝…

SIP协议:AOR和Contact作用

sip协议交互的消息中,通常可以看到一些固定的格式,例如:可以看到消息头中包含“From”,"To","Contact"等字段。这些是起到什么作用呢?From和To是消息交互双方使用的域名,供双方作为位置服务使用。可以通过位置服务将一个URI映射到另一个用户可能使用的…

vlan划分

实验一vlan的创建与划分 一、实验目的: 1.了解vlan的工作原理; 2.学习基于端口划分vlan的方法; 3.了解跨交换机的相同vlan之间的通信; 4.进一步学习交换机端口的配置命令。 二、实验原理: VLAN(Virtual Local Area Network)即虚拟局域网,是一种通过将局域网内的设…

网络技术零基础小白入门课程-深信服内部课程 笔记

02-家庭组网介绍: Q:交换机比路由器速度更快,为什么还比路由器便宜? A:交换机工作在数据链路层,而路由器工作在网络层,因此路由器软件逻辑、硬件成本更高。03-衡量网络性能的指标 Q:在线用户、并发连接用户的概念一样吗? A: 不一样,在线用户是已经访问网站的,并发连接数…

服务器安装centos系统报错

安装centos报错:dracut-initqueue:warning:dracut-initqueue timeout -starting timeout scripts解决方法 U盘启动报错信息 查看U盘的对应 分区 重启电脑 按 e 进入编辑模式 将:vmlinuz initrd=initrd.img inst.stage2=hd:LABEL=CentOS\x207\x20x86_64 rd.live.check quiet改…

【VMware vSphere】使用vSphere Lifecycle Manager(vLCM)管理独立主机和集群的生命周期。

vSphere Lifecycle Manager(vLCM)是 vSphere 7 中引入的一项新功能,它提供了一种集中式、自动化和简单性的方式来管理和升级 vSphere 基础架构组件(如vCenter、ESXi主机和NSX)的生命周期。 VMware 早期用于 vSphere 升级和补丁管理的解决方案称为vSphere Update Manager(…

Qt中的多线程与线程池浅析+实例----冒泡排序和快速排序

转自:https://www.cnblogs.com/wanghongyang/p/14902679.html 今天学习了Qt中的多线程和线程池,特写这篇博客来记录一下 2|02. 多线程 2|12.1 线程类 QThread Qt 中提供了一个线程类,通过这个类就可以创建子线程了,Qt 中一共提供了两种创建子线程的方式,先看一下这个类中提…