网络编程练习题---利用UDP协议实现组播通信

news/2025/3/20 6:35:45/文章来源:https://www.cnblogs.com/fly-home/p/18231570

目录
  • 题目
  • 解析
  • 代码实现

题目

image

解析

  1. 由于该题需要实现组播通信,所以我们需要将套接字文件句柄设置为组播属性,并将需要通信的用户端IP地址,加入组中。
  2. 由于组播通信需要实现一对多发送消息,所以还需要将套接字文件句柄的广播属性一并开启。
  3. 由于该题实现过程使用到了线程相关函数接口,所以编译时需要带上 “-pthread“ 选项

代码实现

/********************************************************************************
*
*	file name:	udp_group.c
*	author	 :  ProgramMonkey_Fly@126.com 
*	date	 :  2024/06/04
*	function :  该案例是掌握UDP协议的组播通信方式
* 	note	 :  
*				想要实现组间通信,只需要对本地地址进行修改后,可实现组间通信,即一个用户
*				发送的消息,组间所有用户都能收到
*   version  :
*
*	CopyRight (c)  2023-2024   ProgramMonkey_Fly@126.com   All Right Reseverd 
*
* ******************************************************************************/
/****************************头文件*********************************************/
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <time.h>/****************************全局变量*********************************************/
int udp_socket;								//用于存储套接字文件的句柄/****************************宏*********************************************/
#define PORT 	  60000 					//用户端运行进程的端口号
#define IP_HOST   "192.168.64.94"			//用户端本地IP地址
#define	IP_GROUP  "226.66.66.66"			//组播通信IP地址/********************************************************************************
*
*	name	 :	recv_time
*	function :  实现获取当前系统时间,并对获取值进行固定格式的处理,获得更好的显示效果
*	param :  
*				none
*				
*	retval	 :  调用成功返回处理后的当前系统时间
*	author	 :  ProgramMonkey_Fly@126.com 
*	date	 :  2024/06/04
* 	note	 : 
*				输出时间的格式固定为:"X年 X月 X日 星期X XX:XX:XX",可根据需要进行修改
*   version  :
* 	
* *****************************************************************************/
char *recv_time()
{//定义一个字符指针,用于存储获取的当前系统时间值char *buf =(char *)calloc(1,128);//定义一个字符数组,用于优化后的星期值char wekday[10];//利用time()获取当前系统时间,并将返回值存储起来time_t systime = time(NULL);//利用localtime()对获取值进行处理,并将处理后的数据写入目标文件中struct tm *systimep = localtime(&systime);systimep->tm_year += 1900;systimep->tm_mon += 1;//对获取星期数值进行判断,并进行美观优化if(systimep->tm_wday == 1){strcpy(wekday, "一");}else if(systimep->tm_wday == 2) {strcpy(wekday, "二");}else if(systimep->tm_wday == 3) {strcpy(wekday, "三");}else if(systimep->tm_wday == 4) {strcpy(wekday, "四");}else if(systimep->tm_wday == 5) {strcpy(wekday, "五");}else if(systimep->tm_wday == 6) {strcpy(wekday, "六");}else if(systimep->tm_wday == 7) {strcpy(wekday, "日");}//将获取值按固定格式写入缓冲区中sprintf(buf, "%d年 %d月 %d日 星期%s %d:%d:%d", systimep->tm_year,systimep->tm_mon,systimep->tm_mday,wekday,systimep->tm_hour,systimep->tm_min,systimep->tm_sec);return buf;
}/********************************************************************************
*
*	name	 :	recv_msg
*	function :  接收信息线程的任务函数
*	param :  
*				none
*				
*	retval	 :  none
*	author	 :  ProgramMonkey_Fly@126.com 
*	date	 :  2024/06/04
* 	note	 :  
*				对应填写的IP地址,可以通过程序开头的宏定义进行修改
*   version  :
* 	
* *****************************************************************************/
void *recv_msg(void *arg)
{//将该线程的属性设置为分离属性,防止线程结束后变为僵尸线程pthread_detach(pthread_self());//绑定服务器的端口和地址struct sockaddr_in  host_addr;host_addr.sin_family 		= AF_INET; 						//协议族,UDP协议固定填写该宏定义host_addr.sin_port   		= htons(PORT);					//想要接收信息进程的端口号host_addr.sin_addr.s_addr   = htonl(INADDR_ANY);			//本地地址,填写该宏定义代表任意网口都可以接收值bind(udp_socket,(struct sockaddr *)&host_addr, sizeof(host_addr));//调用recvfrom等待接收数据,并且接收客户端的网络信息char buf[128] = {0};struct sockaddr_in  client;socklen_t client_len = sizeof(client);//定义一个字符数组用于存储系统时间char *recvtime = (char *)calloc(128,1);while(1){recvfrom(udp_socket,buf,sizeof(buf), 0 ,(struct sockaddr *)&client,&client_len); //函数标识定义为默认属性,即会阻塞recvtime = recv_time();if(client.sin_addr.s_addr == inet_addr(IP_HOST)){bzero(buf,sizeof(buf));continue;}printf("[%s] (%s): %s\n",inet_ntoa(client.sin_addr),recvtime,buf);bzero(buf,sizeof(buf));}
}/********************************************************************************
*
*	name	 :	send_msg
*	function :  发送信息线程的任务函数
*	param :  
*				none
*				
*	retval	 :  none
*	author	 :  ProgramMonkey_Fly@126.com 
*	date	 :  2024/06/04
* 	note	 :  
*				对应填写的IP地址,可以通过程序开头的宏定义进行修改
*   version  :
* 	
* *****************************************************************************/
void *send_msg(void *arg)
{//将该线程的属性设置为分离属性,防止线程结束后变为僵尸线程pthread_detach(pthread_self());//向目标主机发送消息,需要设置目标端口和目标地址char buf[128] = {0};struct sockaddr_in  dest_addr;dest_addr.sin_family 		= AF_INET; 						//协议族,是固定的dest_addr.sin_port   		= htons(PORT);					//服务器运行进程的端口号,必须转换为网络字节序dest_addr.sin_addr.s_addr   = inet_addr(IP_GROUP);			//要发送对象的IP地址,必须转换为点分十进制字符串形式while(1){//阻塞等待获取用户从键盘输入的信息scanf("%s", buf);//发送获取到的用户输入信息sendto(udp_socket,buf,strlen(buf),0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));}}int main(int argc,char *argv[])
{//创建UDP套接字,并存储套接字文件的句柄            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);}//将套接字文件的广播属性设置为开启int flag = 1;socklen_t flag_len = sizeof(flag);setsockopt(udp_socket, SOL_SOCKET, SO_BROADCAST, (void *)&flag, flag_len);//将套接字文件的组播属性设置为开启struct ip_mreqn ip_grop;ip_grop.imr_multiaddr.s_addr = inet_addr(IP_GROUP);//设置组播地址ip_grop.imr_address.s_addr = inet_addr(IP_HOST); //设置要加入组的本地地址ip_grop.imr_ifindex = 0;								 //设置为默认属性,由系统分配端口socklen_t ip_len = sizeof(ip_grop);setsockopt(udp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&ip_grop, ip_len);//创建两个线程,分别用于发送数据和接受数据pthread_t send;pthread_t recv;pthread_create(&send, NULL, send_msg, NULL);pthread_create(&recv, NULL, recv_msg, NULL);//关闭主线程pthread_exit(NULL);return 0;}

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

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

相关文章

游戏渲染调试工具 / 抓帧 / Frame Debugger

有时候要调试一些游戏的渲染过程,可以用以下游戏: 1.Frame Debugger 如果是Unity项目,可以直接在编辑器的Window/Analysis/Frame Debugger打开自带的抓帧工具,对于自己的项目非常合适,能看到每一帧渲染的整个过程 2.RenderDoc 如果要调试的游戏是手机游戏,或者PC上的其他游戏,…

地理空间数据分析与可视化:洞察地理现象的智慧之眼

作为地理信息与遥感领域的探索者,我们深知地理空间数据是解锁地球奥秘的钥匙。在大数据时代背景下,地理空间数据分析与可视化技术正以前所未有的深度与广度,揭示着纷繁复杂的地理现象,为科学研究、政策制定乃至普通民众提供了前所未有的洞察力。今天,我将与您一同深入探讨…

Vue.js 动画与过渡效果实战

title: Vue.js 动画与过渡效果实战 date: 2024/6/4 updated: 2024/6/4 description: 这篇文章介绍了如何在网页设计中使用过渡动画和组件效果,以及如何利用模式和列表展示信息。还提到了使用钩子实现组件间通信的方法。 categories:前端开发tags:过渡 动画 组件 效果 模式 列表…

2024AIGC应用层十大趋势

或许你已经关注到了,过去一年,各种大模型、AIGC应用,已经像电子氧气一样:无、处、不、在。 而且这种“无处不在”可能还会超出你的预期和想象。IDC发布的《2024AIGC应用层十大趋势》报告就明确了“被AIGC包围”,确实是事实。 除此之外,这份权威报告里,还有几点AI的方向也…

`jsonb` 报错 `invalid input syntax for type timestamp with time zone ““

哈喽,大家好,我是木头左!大家好,我是你们的朋友,公众号博主。今天要聊一聊一个常见的数据库问题:jsonb 报错 invalid input syntax for type timestamp with time zone: ""。这个问题可能会影响到你的开发工作,但是别担心,我会用最简单易懂的方式,帮助你解决…

05-Excel基础操作-学习笔记

使用分列工具整理数据 导出的数据是文本文件即以.txt结尾的文件,放入Excel中,是一种常见的操作。 具体操作 打开文本格式的数据,Ctrl+A全选——Ctrl+C复制——新建excel表格——点击A1单元格(注意,这里不要双击)——Ctrl+V粘贴——选中A列——数据选项卡——分列——勾选…

Python神技:pd.read_excel怎样读取多sheet页数据

哈喽,大家好,我是木头左!今天,我要分享的是一个非常实用的Python技能,那就是如何在Python的pandas库中使用pd.read_excel函数来读取Excel文件的多个sheet页数据。 一、为什么要读取Excel的多个sheet页数据? 在数据分析和处理的过程中,经常需要处理包含多个sheet页的Exce…

Frida-Labs

0x1获取了100以内的随机数只需要确保输入的数为随机数的2倍+4即可hook该方法,返回值随意,只要自己输入符合对该值的要求即可 Java.perform(function () {let MainActivity = Java.use("com.ad2001.frida0x1.MainActivity");MainActivity["get_random"].i…

udp协议实现组播功能

/**************************************************************************************************************************************** file name:multicast.c* author :momolyl@126.com* date :2024/06/04* brief :小组实现,小组中的每位成员都…

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 含有特殊字符 - ,所以需要用 [""] 括起来 比如,想实现分类与品牌联动…