网络编程 ----------- 4、组播与广播
1、广播 broadcast
广播是指向同一个网络中所有的主机传输数据只有传输层协议为 UDP协议时,才支持广播
TCP是端对端,广播是一对多 ,所以无法符合其要求。
1)广播地址
广播地址的计算:
子网掩码取反 再和 ip地址 进行按位或运算
例子: ip : 192.168.31.104netmask : 255.255.255.0 ===> 广播地址: 192.168.31.255 ip : 172.4.0.1 netmask :255.255.254.0 ===> 广播地址: 172.4.1.255 ip : 192.168.31.104netmask : 255.255.128.0 ===> 广播地址: 192.168.127.255
全网广播地址: 255.255.255.255
这个没有意义 --> 会造成网络风暴
2)广播的编程流程 (与UDP编程流程类似)
广播的发送者
广播接接收者
3)注意:设置套接字选项
谁需要用到广播, 谁就调用 setsockopt() 函数,设置套接字选项 (详细见表)
使能广播:
级别: SOL_SOCKET
选项: SO_BROADCAST
类型: int
0 禁用
非0 使能
写一个程序,实现 广播的发送和接收 broadcast_sender.c / broadcast_receiver.c broadcast_sender.c 发送者int main( int argc, char *argv[] ){//创建套接字 UDP int sock_fd = socket( AF_INET, SOCK_DGRAM, 0 );if( sock_fd == -1 ){perror( "socket error " );return -1;}printf("sock_fd = %d\n", sock_fd );//设置套接字的选项 --> 使能广播 int n = 1;setsockopt( sock_fd, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n) );//设置广播的ip地址和端口号 struct sockaddr_in addr;addr.sin_family = AF_INET; //协议族 ipv4 addr.sin_port = htons( atoi(argv[2]) ); //端口号 inet_aton( argv[1], &addr.sin_addr ); //广播地址 //发送广播数据 while( 1 ){//输入要发送的数据 char buf[128] = {0};printf("input data : ");fgets( buf, sizeof(buf), stdin );int re = sendto( sock_fd, buf, strlen(buf), 0, (struct sockaddr*)&addr, sizeof(addr) );if( re == -1 ){perror( "sendto error " );break;}//人为定义退出条件if( buf[0] == '#' ){break;}}//关闭套接字 close( sock_fd );}broadcast_receiver.c 接收者(服务器)int main( int argc, char *argv[] ){//创建套接字 UDP int sock_fd = socket( AF_INET, SOCK_DGRAM, 0 );if( sock_fd == -1 ){perror( "socket error " );return -1;}printf("sock_fd = %d\n", sock_fd );//设置套接字的选项 --> 使能广播 int n = 1;setsockopt( sock_fd, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n) );//设置接收广播的ip地址和端口号 struct sockaddr_in addr;addr.sin_family = AF_INET; //协议族 ipv4 addr.sin_port = htons( atoi(argv[2]) ); //端口号 inet_aton( argv[1], &addr.sin_addr ); //广播地址 //绑定套接字 int re = bind( sock_fd, (struct sockaddr*)&addr, sizeof(addr) );if( re == -1 ){perror( "bind error " );close( sock_fd );return -1;}printf("bind success\n");//接收广播数据 while( 1 ){//接收数据 char buf[128] = {0};struct sockaddr_in from_addr;socklen_t len = sizeof(from_addr);re = recvfrom( sock_fd, buf, sizeof(buf), 0, (struct sockaddr*)&from_addr, &len );if( re > 0 ){printf("%s : %s\n", inet_ntoa(from_addr.sin_addr), buf );}else{perror( "recvfrom error " );break;}//人为定义退出条件if( buf[0] == '#' ){break;}}//关闭套接字 close( sock_fd );}
2、组播 (多播) multicast
组播是指 将数据发送给 加入到某个组中的主机上
特点:
1)只有传输层协议为 UDP协议时,才支持组播功能
2)组播地址 ipv4 D类地址
D类地址: 1110 + 多播组号(28bits)
224.0.0.0 ~ 239.255.255.255
3)广播方式 占用带宽,会造成网络风暴
组播是一种折中的方式,只有加入到特定的 某个多播组的主机 才能收到数据
1)多播的代码实现
多播的发送者
多播的接收者
2)加入多播组
设置套接字的选项:
级别: IPPROTO_IP
选项: IP_ADD_MEMBERSHIP
类型: struct ip_mreqn {}
========================================
man 7 ip 进行查看
struct ip_mreqn
{
struct in_addr imr_multiaddr; /* 多播组地址(D类地址) (类似于qq群号)IP multicast group address */
struct in_addr imr_address; /* 接口(网卡)的地址,多播的数据实际走哪个网卡(类似于qq号) IP address of local interface */
...
};
struct in_addr
{
uint32_t s_addr; /* 32位IP地址 */
};
例子: 把 本机ip 加入多播组 224.0.0.1 struct ip_mreqn mreq;mreq.imr_multiaddr.s_addr = inet_addr( "224.0.0.1" ); //多播组地址 mreq.imr_address.s_addr = htonl( INADDR_ANY ); //接口地址 //mreq.imr_address.s_addr = inet_addr( argv[1] ); setsockopt( sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq) );
注意:
要支持多播,需要设置路由表,让数据包从正确的网卡出去,而不是从默认网卡出去
首先 ifconfig 查看本机ip和网卡名字 (如: eth0, eth1, ens33, ... )
sudo route add -net 224.0.0.0 netmask 240.0.0.0 ens33 //加入路由表
sudo route add default gw 172.4.1.1 dev ens33 //设置默认网关
查看内核的IP路由标
route -n
练习: 写一个程序,实现多播的功能 multicast_sender.c / multicast_receiver.c multicast_sender.c 发送者multicast_receiver.c 接收者multicast_sender.c 发送者 int main( int argc, char *argv[] ){//创建套接字 UDP int sock_fd = socket( AF_INET, SOCK_DGRAM, 0 );if( sock_fd == -1 ){perror( "socket error " );return -1;}printf("sock_fd = %d\n", sock_fd );//设置 多播的ip和端口号 struct sockaddr_in addr;addr.sin_family = AF_INET; //协议族 ipv4 addr.sin_port = htons( atoi(argv[2]) ); //端口号 inet_aton( argv[1], &addr.sin_addr ); //多播地址 224.0.0.1 //发送数据while(1){//发送数据 char buf[128] = {0};fgets( buf, sizeof(buf), stdin );int re = sendto( sock_fd, buf, strlen(buf), 0, (struct sockaddr*)&addr, sizeof(addr) );if( re == -1 ){perror( "sendto error " );break;}if( buf[0] == '#' ){break;}}//关闭套接字close( sock_fd );}multicast_receiver.c 接收者 int main( int argc, char *argv[] ){//创建套接字 UDP int sock_fd = socket( AF_INET, SOCK_DGRAM, 0 );if( sock_fd == -1 ){perror( "socket error " );return -1;}printf("sock_fd = %d\n", sock_fd );//设置套接字的选项 --> 把本机ip加入到多播组 224.0.0.1 struct ip_mreqn mreq;mreq.imr_multiaddr.s_addr = inet_addr( argv[1] ); //多播组地址 224.0.0.1 mreq.imr_address.s_addr = htonl( INADDR_ANY ); //接口地址 (本机地址)int re = setsockopt( sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq) ); if( re == -1 ){perror("add membership error ");close( sock_fd );return -1;}printf("add membership success\n");//设置 多播的ip和端口号 struct sockaddr_in addr;addr.sin_family = AF_INET; //协议族 ipv4 addr.sin_port = htons( atoi(argv[2]) ); //端口号 inet_aton( argv[1], &addr.sin_addr ); //多播地址 224.0.0.1 //设置端口号重用 int n = 1;setsockopt( server_sock, SOL_SOCKET, SO_REUSEPORT, &n, sizeof(n) );//绑定套接字 re = bind( sock_fd, (struct sockaddr*)&addr, sizeof(addr) );if( re == -1 ){perror( "bind error " );close( sock_fd );return -1;}printf("bind success\n");//接收数据while(1){//接收数据 char buf[128] = {0};struct sockaddr_in from_addr;socklen_t len = sizeof(from_addr);re = recvfrom( sock_fd, buf, sizeof(buf), 0, (struct sockaddr*)&from_addr, &len );if( re > 0 ){printf("%s : %s\n", inet_ntoa(from_addr.sin_addr), buf );}else {perror( "recvfrom error " );break;}//人为定义退出条件if( buf[0] == '#' ){break;}}//关闭套接字 close( sock_fd );}
相关文章:
网络编程 ----------- 4、组播与广播
1、广播 broadcast 广播是指向同一个网络中所有的主机传输数据只有传输层协议为 UDP协议时,才支持广播 TCP是端对端,广播是一对多 ,所以无法符合其要求。 1)广播地址 广播地址的计算: 子网掩码…...
最短路径算法:Bellman-Ford算法
引言 在图论中,Bellman-Ford算法是一种用于计算单源最短路径的算法。与Dijkstra算法不同,Bellman-Ford算法可以处理带有负权边的图,并且可以检测图中是否存在负权环。本文将详细介绍Bellman-Ford算法的定义、步骤及其实现。 Bellman-Ford算…...
爬虫:xpath模块及昵图网实例
xpath模块 from lxml import etreestr1 """ <div><ul><li class"item-0"><a href"link1.html">first item</a></li><li class"item-1"><a href"link2.html">second…...
高级java每日一道面试题-2024年8月03日-web篇-forward和redirect有什么区别?
如果有遗漏,评论区告诉我进行补充 面试官: forward和redirect有什么区别? 我回答: 在Java Web开发中,forward和redirect是Servlet容器提供的两种用于页面跳转的技术。它们的主要区别在于客户端感知的方式、URL地址的变化、请求对象的共享等方面。下面详细介绍两…...
如何让你的网站拥有更好的体验
在HTML中,属性是用于提供关于HTML元素的额外信息。接下来我们将讲解13个可以让用户拥有更好体验的HTML属性。 Accept 属性 我们可以在<input>元素(仅适用于文件类型)中使用accept属性来指定服务器可以接受的文件类型。 <input ty…...
opencascade AIS_TypeFilter AIS_XRTrackedDevice源码学习
opencascade AIS_TypeFilter 前言 通过它们的类型选择交互对象。该过滤器会对本地上下文中的每个交互对象提出问题, 以确定它是否具有非空的所有者,并且如果是,则检查它是否是所需类型。 如果对象在每种情况下都返回 true,则保留…...
使用Spring AOP监控指定方法执行时间
文章目录 一、加入pom依赖二、切面类和注解三、执行方法 一、加入pom依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>二、切面类和注解 import java.lang.…...
最新CSS3纵向菜单的实现
纵向菜单 通过下面例子,你会知道把列表转换成菜单的关键技术 a中的#是URL的占位符可以点击,真正用途中写实际URL <nav class"list1"><ul><li><a href"#">Alternative</a></li><li><…...
GooLeNet模型搭建
一、model import torch from torch import nn from torchsummary import summaryclass Inception(nn.Module):def __init__(self, in_channels, c1, c2 , c3 , c4):super(Inception, self).__init__()self.ReLU nn.ReLU()#路线1:1x1卷积self.p1_1 nn.Conv2d(in_channels i…...
使用ThreadLocal来存取单线程内的数据
一.什么是ThreadLocal? ThreadLocal,即线程本地变量。如果你创建了一个 ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的一个本地拷贝,多个线程操作这个变量的时候,实际是在操作自己本地内存里面的变量&…...
elasticsearch教程
1. 单点部署(rpm): #提前关闭firewalld,否则无法组建集群 #1. 下载ES rpm包 ]# https://www.elastic.co/cn/downloads #2. 安装es ]# rpm -ivh elasticsearch-7.17.5-x86_64.rpm #3. 调整内核参数(太低的话es会启动报错) echo "vm.max_map_count655360 fs.file-max 655…...
Arrays、Lambda表达式、Collection集合
1. Arrays 1.1 操作数组的工具类 方法名说明public static String toString(数组)把数组拼接成一个字符串public static int binarySearch(数组,查找的元素)二分查找法查找元素public static int[] copyOf(原数组,新数组长度)拷贝数组public static int[] copyOfRange(原数组…...
2024年前端趋势:全栈或许是不容错过的选择!
近年来,前端开发的技术不断推陈出新,2024年也不例外。在这个变化迅速的领域,全栈开发逐渐成为一股不容忽视的趋势。无论你是经验丰富的开发者,还是刚刚入门的新手,掌握全栈技术都能让你在竞争中脱颖而出。而在这个过程…...
MySQL 实战 45 讲(01-05)
本文为笔者学习林晓斌老师《MySQL 实战 45 讲》课程的学习笔记,并进行了一定的知识扩充。 sql 查询语句的执行流程 大体来说,MySQL 可以分为 Server 层和存储引擎层两部分。 Server 层包括连接器、查询缓存、分析器、优化器和执行器。 连接器负责接收客…...
仓颉编程语言入门 -- Array数组详解
仓颉编程语言入门 – Array数组详解 一. 如何创建Array数组 我们可以使用 Array 类型来构造单一元素类型,有序序列的数据。 1.仓颉使用 Array 来表示 Array 类型。T 表示 Array 的元素类型,T 可以是任意类型 , 类似于泛型的概念 var arr:Array<St…...
C#初级——简单单例模式使用
单例模式 单例模式是一种常用的软件设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例,通过单例模式防止私有成员被多次引用,防止数据被随意纂改。本文使用的是线程不安全的懒汉式单例。 创建单例模式 首…...
2024.07.29 校招 实习 内推 面经
地/球🌍 : neituijunsir 交* 流*裙 ,内推/实习/校招汇总表格 1、校招 | 美/团// 快驴、小象、优/选/事/业/部2024年校/园/招聘(内推) 校招 | 美团快驴、小象、优选事业部2024年校园招聘(内推ÿ…...
速盾:爬虫攻击和cc攻击的区别是什么?
爬虫攻击和CC(Distributed Denial of Service)攻击是网络安全领域两种不同类型的攻击方式。尽管它们都涉及对目标网站或服务器的非法访问,但它们的目的、方法和影响各不相同。在接下来的文章中,我们将详细介绍这两种攻击方式的区别…...
Tomcat与Nginx的区别详解
目录 引言Tomcat概述 Tomcat的历史Tomcat的架构Tomcat的功能Nginx概述 Nginx的历史Nginx的架构Nginx的功能Tomcat与Nginx的区别 架构上的区别...
【大模型从入门到精通5】openAI API高级内容审核-1
这里写目录标题 高级内容审核利用 OpenAI 内容审核 API 的高级内容审核技术整合与实施使用自定义规则增强审核综合示例防止提示注入的策略使用分隔符隔离命令理解分隔符使用分隔符实现命令隔离 高级内容审核 利用 OpenAI 内容审核 API 的高级内容审核技术 OpenAI 内容审核 AP…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
