udp协议实现组播功能
/**************************************************************************************************************************************
 *
 *   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_ANY
	bind(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;
}
运行结果:

udp协议实现组播功能的更多相关文章
- Android为TV端助力:UDP协议(接收组播和单播)
		
private static String MulticastHost="224.9.9.98";private static int POST=19999;private sta ...
 - 协议无关组播-密集模式 PIM-DM
		
一.组播路由协议 (一) 路由器依靠转发项来转发组播数据包.转发项的生成则是组播路由协议所要完成的任务.组播路由协议有距离矢量组播路由协议(DVMRP).协议无关组播-密集模式(PIM-DM).协议无 ...
 - UDP单播和组播使用SO_REUSEADDR 测试结果
		
UDP单播通信 一. 预置条件 A.B在同一台机器,网络中存在往A.B所在的机器的8888端口发送单播UDP数据 A:端口复用绑定在端口8888上 B:端口复用绑定在端口8888上操作步骤:(1)先启 ...
 - netty的Udp单播、组播、广播实例+Java的Udp单播、组播、广播实例
		
网络上缺乏netty的udp的单播.组播案例,经过一番学习总结之后终于把这两个案例调通,下面把这两个案例的代码放在这里分享一下. 首先推荐博文: http://colobu.com/2014/10/2 ...
 - 计算机网络之网络层IP组播(IGMP、组播路由选择协议、组播地址)
		
文章转自:https://blog.csdn.net/weixin_43914604/article/details/105318560 学习课程:<2019王道考研计算机网络> 学习目的 ...
 - 协议无关组播--稀疏模式  PIM-SM
		
一. 1)PIM-SM 1.PIM-SM转发.加入 PIM-SM适合于接收成员较少的环境.它与DM有何显著的区别?先看PIM-SM转发机制. 转发: 当组播数据到达路由器时,路由器也会去创建转发项.转 ...
 - UDP广播,组播服务器
		
广播 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ ...
 - android怎么打开wifi的组播功能
		
http://android.tgbus.com/Android/tutorial/201204/418987.shtml
 - 《TCP/IP 详解 卷1:协议》第 9 章:广播和本地组播(IGMP 和 MLD)
		
我已经懒了,卷一已经是去年年底看完的,但怎么说卷一的坑开了就要填完啊-- 广播和本地组播(IGMP 和 MLD) 引言 有 4 种 IP 地址,单播(unicast).任播(anycast).组播(m ...
 - Android上UDP组播无法接收数据的问题
		
最近,想做一个跨平台的局域网的文件传输软件,思路是组播设备信息,TCP连接传输文件.于是进行了一次简单的UDP组播测试,发现Android对于UDP组播接收数据的支持即极为有限. 部分代码如下 pac ...
 
随机推荐
- Java序列化和反序列化 Serializable BeanUtils.copyProperties赋值属性方法
			
Java序列化和反序列化 Serializable BeanUtils.copyProperties赋值属性方法 package com.example.core.mydemo.java; impor ...
 - python实现推送消息到微信公众号
			
使用到库: Requests 实现方式: 微信已开放了对应的接口,直接通过python的requests库,发起请求,实现推送消息到公众号 微信公众号准备: 1.没有注册微信公众号,可以使用微信提供的 ...
 - 开启PHP-GD库
			
话不多说,上教程 环境 CentOS7 1. 安装php-gd yum install php-gd 2. 定位gd.so位置 rpm -qal | grep gd.so #第一行即是 3. 定位配置 ...
 - hive第二课:Hive3.1.2概述与基本操作(修改版)
			
Hive3.1.2概述与基本操作 1.Hive基本概念 1.1 Hive简介 Hive本质是将SQL转换为MapReduce的任务进行运算,底层由HDFS来提供数据存储,说白了hive可以理解为一个将 ...
 - ARC108C
			
考虑一颗树怎么染色. 每个子节点染成边的颜色,如果与父亲节点相同,就随便染色(这条边的限制已经被父亲节点满足). 那么一定可以染色. 所以把原图跑最小生成树再按上述方法染色即可. 倘若原图不连通,那么 ...
 - win11 vmware16 启动虚拟机引起蓝屏
			
前言 在win11 上安装 vmware16, 之后安装ubuntu16时,一打开ubuntu虚拟机就触发系统蓝屏. 正文 我改了两个地方: 控制面板->程序->启用或关闭Windows功 ...
 - react为什么不用数组的下标来绑定key
			
最近在看一本名叫<深入浅出React和Redux>这一书,里面谈到了react的dom更新比对,记录一下. 假设有这么一个组件 <ul> <ListItem text=& ...
 - VirtualBox中Ubuntu 22.04 Server支持kvm
			
kvm简介 KVM 是 Kernel-based Virtual Machine 的缩写,是一种用于虚拟化的开源硬件虚拟化技术. 使用 Linux 内核的虚拟化模块,将物理服务器划分为多个虚拟机. K ...
 - 载均衡技术全解析:Pulsar 分布式系统的最佳实践
			
背景 Pulsar 有提供一个查询 Broker 负载的接口: /** * Get load for this broker. * * @return * @throws PulsarAdminExc ...
 - [oeasy]python018_ 如何下载github仓库_git_clone_下载仓库
			
继续运行 回忆上次内容 上次从 2行代码 进化到了 万行代码 命令 作用 yy 复制光标所在行代码 到剪贴板 p 粘贴 剪贴板中的内容 9999p 将剪贴板中的代码粘贴9999次 保存运行一条龙 :w ...