网络编程之udp学习之udp的多播(组播)和广播案例03

2023-10-30

概述,关于多播,广播这些我Qt相关的文章 也有讲述过。

https://blog.csdn.net/weixin_44517656/article/details/105950817	//ip相关知识
https://blog.csdn.net/weixin_44517656/article/details/105959683	//多播与广播
https://blog.csdn.net/weixin_44517656/article/details/105970733	//qt实现广播与组播案例

1 多播(组播)

1.1
组播组可以是永久的也可以是临时的。组播组地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。永久组播组中成员的数量都可以是任意的,甚至可以为零。那些没有保留下来供永久组播组使用的ip组播地址,可以被临时组播组利用。

224.0.0.0224.0.0.255		为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;
224.0.1.0224.0.1.255		是公用组播地址,可以用于Internet;欲使用需申请。
224.0.2.0238.255.255.255	为用户可用的组播地址(临时组地址),全网范围内有效;
239.0.0.0239.255.255.255	为本地管理组播地址,仅在特定的本地范围内有效。

可使用ip ad命令查看网卡编号:
在这里插入图片描述
if_nametoindex 命令可以根据网卡名,获取网卡序号。由于我赖得安装所以没有测试。

1.2 案例
组播在linux的情况就是:服务器需要将组播地址赋值给组播权限struct ip_mreqn group结构体,然后再给客户端赋值多一次组播地址即可。而客户端只需要加入一次组播地址即可。
这就相当于每个用户自己绑定一次自己的ip和端口后(服务器端口为私有,客户端端口为组播端口),然后利用setsockopt函数加入组播地址即可。例如我们的qq群,微信群。
server.c

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>

#define SERVER_PORT 6666
#define MAXLINE 1500

#define GROUP "239.0.0.2"	/* 组播地址 */
//#define GROUP "224.0.0.2"	/* 组播地址 */
#define CLIENT_PORT 9000	/* 客户端需要加入的组播端口 */

// struct ip_mreqn {
// 		struct in_addr	imr_multiaddr;			/* IP multicast address of group */
// 		struct in_addr	imr_address;			/* local IP address of interface */
// 		int 			imr_ifindex;			/* Interface index */
// };

int main(void)
{
    int sockfd;
    struct sockaddr_in serveraddr, clientaddr;
    char buf[MAXLINE] = {0};
    struct ip_mreqn group;

	/* 初始化 */
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);                /* 网络(tcp,udp)参1都是使用AF_INET,参2使用SOCK_STREAM或者SOCK_DGRAM,tcp一般前者,udp后者 */
    if (sockfd < 0){      
        printf ("socket error\n");     
        exit (1);   
    }
    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;                        /* IPv4 */
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);         /* 本地任意IP INADDR_ANY = 0 */
    serveraddr.sin_port = htons(SERVER_PORT);
	if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0){      
        printf ("bind error\n");     
        exit (1);   
    }

	/* 设置组播地址IP_MULTICAST_IF和组播权限struct ip_mreqn group */
    inet_pton(AF_INET, GROUP, &group.imr_multiaddr);        /* 设置组地址 */
    inet_pton(AF_INET, "0.0.0.0", &group.imr_address);      /* 本地任意IP */
    group.imr_ifindex = if_nametoindex("eth0");             /* 给出网卡名,转换为对应编号: eth0 --> 编号  命令:ip ad */
    setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, &group, sizeof(group));  
	
	/* 构造 client 地址 IP+端口。 IPv4,239.0.0.2+9000 */
    bzero(&clientaddr, sizeof(clientaddr));                 
    clientaddr.sin_family = AF_INET;
    inet_pton(AF_INET, GROUP, &clientaddr.sin_addr.s_addr);
    clientaddr.sin_port = htons(CLIENT_PORT);

    int i = 0;
    while (1) {
        memset(buf, 0x00, MAXLINE);
        sprintf(buf, "itcast %d", i++);
        printf("%s\n", buf);
        //fgets(buf, sizeof(buf), stdin);
        sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));
        sleep(1);
    }

    close(sockfd);

    return 0;
}

client.c

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>

#define SERVER_PORT 6666

#define GROUP "239.0.0.2"	/* 组播地址,需要和服务器保持一致 */
//#define GROUP "224.0.0.2"	/* 组播地址,需要和服务器保持一致 */
#define CLIENT_PORT 9000	/* 客户端需要加入的组播端口 */

int main(int argc, char *argv[])
{
    struct sockaddr_in localaddr;
    int confd;
    ssize_t len;
    char buf[BUFSIZ];
    struct ip_mreqn group;                                                  /* 组播结构体 */

	/* 初始化 */
    confd = socket(AF_INET, SOCK_DGRAM, 0);
    if (confd < 0){      
        printf ("socket error\n");     
        return -1;   
    }
    bzero(&localaddr, sizeof(localaddr));
    localaddr.sin_family = AF_INET;
    inet_pton(AF_INET, "0.0.0.0" , &localaddr.sin_addr.s_addr);
    localaddr.sin_port = htons(CLIENT_PORT);
    if (bind(confd, (struct sockaddr *)&localaddr, sizeof(localaddr)) < 0){      
        printf ("bind error\n");     
        return -1;      
    }

	/* 设置client加入多播组IP_ADD_MEMBERSHIP */
    inet_pton(AF_INET, GROUP, &group.imr_multiaddr);                        /* 设置组地址 */
    inet_pton(AF_INET, "0.0.0.0", &group.imr_address);                      /* 使用本地任意IP添加到组播组 */
    group.imr_ifindex = if_nametoindex("eth0");                             /* 通过网卡名-->编号 ip ad */
    setsockopt(confd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group));

    while (1) {
        len = recvfrom(confd, buf, sizeof(buf), 0, NULL, 0);	/* 接收服务器发过来的广播消息 */
        write(STDOUT_FILENO, buf, len);
    }
    close(confd);

    return 0;
}

2 广播

server.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>

#define SERVER_PORT 8000                                    /* 无关紧要 */
#define MAXLINE 1500
//#define BROADCAST_IP "192.168.42.255"						/* 广播地址 */
#define BROADCAST_IP "255.255.255.255"						/* 广播地址 */
#define CLIENT_PORT 9000                                    /* 广播端口(重要) */

int main(void)
{
    int sockfd;
    struct sockaddr_in serveraddr, clientaddr;
    char buf[MAXLINE];

    /* 构造用于UDP通信的套接字 */
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);				/* 网络(tcp,udp)参1都是使用AF_INET,参2使用SOCK_STREAM或者SOCK_DGRAM,tcp一般前者,udp后者 */
    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;                        /* IPv4 */
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);         /* 本地任意IP INADDR_ANY = 0 */
    serveraddr.sin_port = htons(SERVER_PORT);
    bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));

	/* 设置广播SO_BROADCAST */
    int flag = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag));

    /*构造 client 地址 IP+端口  广播ip+9000 */
    bzero(&clientaddr, sizeof(clientaddr));
    clientaddr.sin_family = AF_INET;
    inet_pton(AF_INET, BROADCAST_IP, &clientaddr.sin_addr.s_addr);
    clientaddr.sin_port = htons(CLIENT_PORT);

    int i = 0;
    while (1) {
        //sprintf(buf, "Drink %d glasses of water\n", i++);
        memset(buf, 0x00, MAXLINE);
        sprintf(buf, "Drink %d glasses of water", i++);
        printf("%s\n", buf);
        //fgets(buf, sizeof(buf), stdin);
        sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));
        sleep(1);
    }
    close(sockfd);
    return 0;
}

client.c

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define SERVER_PORT 8000
#define MAXLINE 4096
#define CLIENT_PORT 9000

int main(int argc, char *argv[])
{
    struct sockaddr_in localaddr;
    int confd;
    ssize_t len;
    char buf[MAXLINE];

    confd = socket(AF_INET, SOCK_DGRAM, 0);
    bzero(&localaddr, sizeof(localaddr));
    localaddr.sin_family = AF_INET;
    inet_pton(AF_INET, "0.0.0.0" , &localaddr.sin_addr.s_addr);
    localaddr.sin_port = htons(CLIENT_PORT);
    int ret = bind(confd, (struct sockaddr *)&localaddr, sizeof(localaddr));  //显示绑定不能省略
    if (ret < 0)
        printf("...bind error...\n");

    while (1) {
        printf("len=%d\n", len);
        len = recvfrom(confd, buf, sizeof(buf), 0, NULL, 0);
        printf("len=%d\n", len);
        write(STDOUT_FILENO, buf, len);
    }
    close(confd);

    return 0;
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

网络编程之udp学习之udp的多播(组播)和广播案例03 的相关文章

  • Linux 中热插拔设备时检测设备是否存在

    我正在运行 SPIcode http lxr free electrons com source drivers spi spi omap2 mcspi c在熊猫板上 我想知道其中的哪个功能code http lxr free electr
  • 为 Qt 应用程序创建 Linux 安装

    我刚刚用 Qt Creator 制作了一个很棒的程序 我对自己很满意 如何将其从台式机移至笔记本电脑 那么 最好的方法是安装程序 对吗 对于 Ubuntu 这是一个 Debian 软件包 对吗 我怎么做 有人这样做过吗 他们可以分享 QT
  • 在 Ubuntu 16.04 上找不到 printf.c

    我最近切换到Ubuntu 16 04 我在用vscode作为 Ubuntu 上的 IDE 我配置了其他语言 但我无法做到这一点C C 我创建c cpp properties json launch json tasks json 当我开始编
  • 如何让“grep”从文件中读取模式?

    假设有一个很大的文本文件 我只想打印与某些模式不匹配的行 显然 我可以使用egrep v patter1 pattern2 pattern3 现在 如果所有这些模式都在一个文本文件中怎么办 最好的制作方法是什么egrep从文件中读取模式 g
  • sleep 0 有特殊含义吗?

    我看到很多用法sleep 0在我的一个客户项目中 代码看起来像这样 while true sleep 0 end 阅读一些像这样的答案this https stackoverflow com questions 3727420 signif
  • C 程序从连接到系统的 USB 设备读取数据

    我正在尝试从连接到系统 USB 端口的 USB 设备 例如随身碟 获取数据 在这里 我可以打开设备文件并读取一些随机原始数据 但我想获取像 minicom teraterm 这样的数据 请让我知道我可以使用哪些方法和库来成功完成此操作以及如
  • 劫持系统调用

    我正在编写一个内核模块 我需要劫持 包装一些系统调用 我正在暴力破解 sys call table 地址 并使用 cr0 来禁用 启用页面保护 到目前为止一切顺利 一旦完成 我将公开整个代码 因此如果有人愿意 我可以更新这个问题 无论如何
  • 如何查找连接到 AF_INET 套接字的客户端的 UID?

    有什么方法或类似的东西ucred for AF UNIX如果是AF INET插座 TCP在我的例子中 找出连接到我的套接字的客户端的UID 还有 proc net tcp但它显示了UID of the creator插座的而不是连接的cli
  • 归档文件系统或格式

    我正在寻找一种文件类型来存储已退役系统的档案 目前 我们主要使用 tar gz 但从 200GB tar gz 存档中查找并提取几个文件是很麻烦的 因为 tar gz 不支持任何类型的随机访问读取规定 在你明白之前 使用 FUSE 安装 t
  • 没有可用的符号表信息

    我正在测试第三方的库 它崩溃了 当我想查看崩溃的原因时 我的 gdb 告诉我没有可用的调试符号 Program received signal SIGSEGV Segmentation fault Switching to Thread 0
  • 在 /dev/input/eventX 中写入事件需要哪些命令?

    我正在开发一个android需要将触摸事件发送到 dev input eventX 的应用程序 我知道C执行此类操作的代码结构如下 struct input event struct timeval time unsigned short
  • SONAR - 使用 Cobertura 测量代码覆盖率

    我正在使用声纳来测量代码质量 我不知道的一件事是使用 Cobertura 测量代码覆盖率的步骤 我按照以下步骤操作http cobertura sourceforge net anttaskreference html http cober
  • .NET Core 中的跨平台文件名处理

    如何处理文件名System IO以跨平台方式运行类以使其在 Windows 和 Linux 上运行 例如 我编写的代码在 Windows 上完美运行 但它不会在 Ubuntu Linux 上创建文件 var tempFilename Dat
  • 并行运行 make 时出错

    考虑以下制作 all a b a echo a exit 1 b echo b start sleep 1 echo b end 当运行它时make j2我收到以下输出 echo a echo b start a exit 1 b star
  • Godaddy 托管上的 CakePHP 控制台

    我一直在努力让我的 CakePHP 网站在 Godaddy 网格托管 帐户上运行 我的蛋糕应用程序设置是从帐户的子目录托管的 并且可以通过子域访问 我必须调整我的 htaccess 文件才能使其正常工作 现在我需要让 CakePHP 控制台
  • 为什么我收到的数据包数据大小大于mss?

    我在两台 PC 上使用 ifconfig ethX mtu 300 修改了 MTU 并使用 netperf 测试网络 我用 WireShark 嗅探了 SYN 数据包中的 MSS 260 但我得到了一些大于 260 的数据包 为什么 嗅探器
  • 如何修复“iptables:没有该名称的链/目标/匹配”?

    我在我的 Linux 嵌入式系统上构建并安装了 iptables 如果我列出所有规则 则一切正常 iptables list Chain INPUT policy ACCEPT target prot opt source destinat
  • 强制卸载 NFS 安装目录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案
  • 如何使用 xterm.js 创建基于 Web 的终端以 ssh 进入本地网络上的系统

    我偶然发现了这个很棒的图书馆xterm js https xtermjs org 这也是 Visual Studio Code 终端的基础 我有一个非常普遍的问题 我想通过基于网络的终端 不在网络中 可能位于 aws 服务器上 访问本地网络
  • 如何在bash中使用jq从变量中包含的json中提取值

    我正在编写一个 bash 脚本 其中存储了一个 json 值 现在我想使用 Jq 提取该 json 中的值 使用的代码是 json val code lyz1To6ZTWClDHSiaeXyxg redirect to http examp

随机推荐

  • 人工智能基础篇

    人工智能基础篇 本篇目录 一 人工智能 机器学习 深度学习的关系 1 关系图 2 人工智能 3 人类智能过程 4 机器学习 5 深度学习 二 人工智能研究的领域 三 人工智能的应用场景 1 计算机视觉 2 语音技术 3 自然语言处理 4 决
  • C++学习第二弹之整数数据类型

    本文主要介绍C 数 整数 包括创建变量和编写各种类型的常量 整数 不同C 数据类型使用不同的内存来存储整数 内存越大能够表示的数值就越大 同时有的类型可以表示正值和负值 有些不能表示负值 C 基本整型有char short int long
  • C++设计模式由浅入深(一)—— 继承和多态

    一 继承和多态 C 首先是一个面向对象的语言 对象是C 程序的基石 通过类的继承和派生 软件工程师可以自由表达对软件系统中各个部分之间的关系与交互逻辑 定义各个组件之间的接口和实现 有秩序地组织起数据结构和代码 本书的目的不是为了教授C 语
  • 项目——电子词典(客户端、服务器交互,字典导入,单词查询)

    一 项目要求 登录注册功能 不能重复登录 重复注册 单词查询功能 历史记录功能 存储单词 意思 以及查询时间 基于TCP 支持多客户端连接 采用数据库保存用户信息与历史记录 将dict txt的数据导入到数据库中保存 按下ctrl c退出客
  • Fiddler抓包工具总结

    序章 Fiddler是一个蛮好用的抓包工具 可以将网络传输发送与接受的数据包进行截获 重发 编辑 转存等操作 也可以用来检测网络安全 反正好处多多 举之不尽呀 当年学习的时候也蛮费劲 一些蛮实用隐藏的小功能用了之后就忘记了 每次去网站上找也
  • qt 智能指针介绍

    简介 Qt 提供了很多智能指针 比较常见的有 QPointer QSharedDataPointer QSharedPointer QWeakPointer 和 QScopedPointer 描述 QPointer 4 0 已经过时 可以被
  • php fastcgi,配置apache以fastcgi运行php

    apache默认是用自带的mod php模块运行php 现在我们介绍使用fastcgi来执行php脚本 先说下fastcgi的优点 Fastcgi的优点 从稳定性上看 fastcgi是以独立的进程池运行来cgi 单独一个进程死掉 系统可以很
  • 解决高德地图AMap is not defined

    传送门 https blog csdn net qq 36317441 article details 77187369 总结一下 就是将script 标签引入的高德地图地址 放到body中
  • Leetcode 面试题 01.06.字符串压缩(Compress String LCCI)

    Leetcode 面试题 01 06 字符串压缩 1 题目描述 Leetcode题目链接 字符串压缩 利用字符重复出现的次数 编写一种方法 实现基本的字符串压缩功能 比如 字符串aabcccccaaa会变为a2b1c5a3 若 压缩 后的字
  • 虚拟机占用磁盘越来越大的解决方案大总结

    原文链接 https blog csdn net Shine Su article details 119676646 作者 填坑小霸王 在电脑上安装Vmware 安装ubuntu16 04 进行开发 使用过程中没有在意 忽然有一天发现磁盘
  • 【esp32&lvgl】-2.1 # esp32移植lvgl7驱动st7789屏幕(ESP-IDF框架)

    目录 一 前言 二 代码 三 硬件说明 四 ESP IDF设置 重要 五 屏幕偏移修改驱动文件 参考资料 一 前言 前几天在ardiuno框架下基于platformIO用TFT eSPI库实现了lvgl库的移植 这种方法虽然在lvgl的版本
  • 电源系列1:LDO 基本 原理(一)

    微信公众号 工程师看海 后台回复 LDO仿真文件 转载请注明原文地址 https blog csdn net u013608300 article details 108994763 1 前言 目前市场上无论什么电子产品 只要涉及到电就必须
  • ssh 运行 java,通过ssh将Java应用程序作为后台进程运行

    I m currently developing a simple deployment script for vms running ubuntu All these machines are supposed to run a java
  • 基于Springboot的SSO单点登陆系统的登陆操作实战

    一 前言 1 使用环境 SpringBoot2 X MyBatis 基于redis存储的springSession 2 基础学习 关于SSO的基础学习可以参考该文章 单点登录 SSO 从原理到实现 代码风格使用的是晓风轻的代码规范 对于其中
  • c语言的文法,c语言实现First文法

    最近编译原理课程实验做LL 1 中的First和Follow文法的算法实现 百度了半天 要么是要钱 要么是觉得好复杂 作为学渣的我看不懂 那为了完成实验 只能自己慢慢搞出来 由于之前的课也没怎么听 研究这两个文法都用了好长时间 那么关于Fi
  • Maven下Druid连接池配置及使用

    1 在pom xml中导入架包及jdbc架包
  • 如何做一个成功的系统架构师

    首先 何谓系统架构师 IBM工程师的说明是 架构师的主要责任是提供开发人员和项目经理之间的共用沟通媒体 他们负责让业务规则及需求与工程实践及限制相适应 以确保成功 中文Wiki上的说明是 系统架构师负责设计系统整体架构 从需求到设计的每个细
  • Pytorch学习(3):Tensor合并、分割与基本运算

    文章目录 前言 一 合并Cat Stack 1 Cat 2 Stack 二 分割Split Chunk 1 Split 2 Chunk 三 基本运算 1 加减乘除 2 矩阵乘法mm matmul 3 幂运算 4 指数exp 对数log 5
  • 从一年开发经验的视角看如何优雅编程

    编程绝非易事 需要大家在日常工作中仔细钻研 下面我们从实际业务开发的角度来分析一下如何优雅地进行编程 简单可以总结几点 1 整体理解业务 2 从开发角度分解业务 3 结合各业务点整体分析系统结构 4 针对每一个业务点进行边界分析 5 对每个
  • 网络编程之udp学习之udp的多播(组播)和广播案例03

    概述 关于多播 广播这些我Qt相关的文章 也有讲述过 https blog csdn net weixin 44517656 article details 105950817 ip相关知识 https blog csdn net weix