UNP卷一chapter20 广播

2024-04-25 19:48
文章标签 广播 chapter20 unp

本文主要是介绍UNP卷一chapter20 广播,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、单播、广播及多播等不同寻址方式

类型IPv4IPv6TCPUDP所标识接口数递送到接口数
单播YYYY一个一个
任播*Y尚没有Y一组一组中的一个
多播可选Y
Y一组一组中的全体
广播Y

Y全体全体

表中要点:

i、多播支持在IPv4中是可选的,在IPv6中却是必需的

ii、IPv6不支持广播。使用广播的任何IPv4应用程序一旦移植到IPv6就必须改用多播重新新编写

iii、广播和多播要求用于UDP或原始IP,不能用于TCP

广播的用途有:资源发现,多个客户主机与单个服务器主机通信的局域网环境中尽量减少分组流通。如下,

ARP:在子网中广播一个请求说“IP地址为a.b.c.d的系统亮明身份,请告诉我你的硬件地址”。ARP使用链路层广播而不是IP层广播。

DHCP:在子网有DHCP服务器下,DHCP客户主机向子网发送广播地址以请求获取自己的IP地址、子网掩码以及本子网的受限广播地址。

还有NTP、路由守护进程等等运用广播的例子。

2、广播地址

i、子网定向广播地址:{子网ID,-1}(此为IPv4地址表示方法,子网ID表示由子网掩码覆盖的连续位,主机ID表示以外的位,-1表示所有位均为1的字段)

ii、受限广播地址:{-1,-1}或255.255.255.255。路由器从不转发目的地址为255.255.255.255的IP数据报。

3、UDP数据报广播示例

目的IP地址是所在以太网的子网定向广播地址,于是把它映射成48位全为1的以太网地址:ff:ff:ff:ff:ff:ff。这个地址使得该子网上的每一个以太网接口都接收该帧。

右侧主机把该UDP数据报传递给绑定端口520的应用进程。一个应用进程无需就为接收广播UDP数据报而进行任何特殊处理:它只需要创建一个UDP套接字,并把应用的端口号摁绑到其上。(假设捆绑的IP地址是典型的INADDR_ANY。)

中间的主机没有任何应用进程绑定的UDP端口520。于是该主机UDP代码丢弃这个已收取的数据报。切记,该主机绝不能发送一个ICMP端口不可达消息,因为这么做可能产生广播风暴,导致网络拥塞。

4、竞争状态(当有多个进程访问共享的数据,而正确结果取决于进程的执行顺序)

三种方法解决在使用广播的dg_cli函数中竞争状态问题。

i、用pselect阻塞和解阻塞信号(需要了解pselect的用法,见书上6.9节P142)

#include	"unp.h"static void	recvfrom_alarm(int);void
dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{int				n;const int		on = 1;char			sendline[MAXLINE], recvline[MAXLINE + 1];fd_set			rset;sigset_t		sigset_alrm, sigset_empty;//生成两个信号集socklen_t		len;struct sockaddr	*preply_addr;preply_addr = Malloc(servlen);Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));//开启套接字广播选项FD_ZERO(&rset);Sigemptyset(&sigset_empty);//声明信号集,初始化为空集Sigemptyset(&sigset_alrm);//声明信号集,初始化为空集Sigaddset(&sigset_alrm, SIGALRM);//再在信号集sigset_alarm,打开与SIGALRM对应的位Signal(SIGALRM, recvfrom_alarm);while (Fgets(sendline, MAXLINE, fp) != NULL) {Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);//调用sigprocmask函数,阻塞SIGALRM(即信号发生时,不会立即调用信号处理函数)alarm(5);for (; ; ) {FD_SET(sockfd, &rset);n = pselect(sockfd + 1, &rset, NULL, NULL, NULL, &sigset_empty);//最后一个参数表示信号集为空集,意味着在pselect调用期间if (n < 0) {                                                    //SIGALRM不阻塞,当pselect返回时,又自动将SIGALRM设置为阻塞if (errno == EINTR)break;elseerr_sys("pselect error");}else if (n != 1)err_sys("pselect error: returned %d", n);len = servlen;n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);recvline[n] = 0;	/* null terminate */printf("from %s: %s",Sock_ntop_host(preply_addr, len), recvline);}}free(preply_addr);
}static void
recvfrom_alarm(int signo)
{return;		/* just interrupt the recvfrom() */
}
ii、使用sigsetjump和siglongjmp
#include	"unp.h"
#include	<setjmp.h>static void			recvfrom_alarm(int);
static sigjmp_buf	jmpbuf;//分配一个将由本函数及其信号处理函数使用的跳转Buffervoid
dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{int				n;const int		on = 1;char			sendline[MAXLINE], recvline[MAXLINE + 1];socklen_t		len;struct sockaddr	*preply_addr;preply_addr = Malloc(servlen);Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));Signal(SIGALRM, recvfrom_alarm);//捕获SIGALRM,并执行信号处理函数recvfrom_alarmwhile (Fgets(sendline, MAXLINE, fp) != NULL) {Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);alarm(5);for (; ; ) {if (sigsetjmp(jmpbuf, 1) != 0)//建立跳转缓冲区后返回0break;len = servlen;n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);recvline[n] = 0;	/* null terminate */printf("from %s: %s",Sock_ntop_host(preply_addr, len), recvline);}}free(preply_addr);
}static void
recvfrom_alarm(int signo)
{siglongjmp(jmpbuf, 1);//当SIGALRM信号被递交时,调用siglongjmp,跳转至sigsetjmp设置的缓冲区,并返回siglongjmp的第二个参数1,从而导致dg_cli的for循环结束
}

iii、使用从信号处理函数到主控函数的IPC

#include	"unp.h"static void	recvfrom_alarm(int);
static int	pipefd[2];void
dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{int				n, maxfdp1;const int		on = 1;char			sendline[MAXLINE], recvline[MAXLINE + 1];fd_set			rset;socklen_t		len;struct sockaddr	*preply_addr;preply_addr = Malloc(servlen);Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));Pipe(pipefd);//创建一个普通Unix管道,返回两个描述符,pipefd[0](读入),pipefd[1](写出)maxfdp1 = max(sockfd, pipefd[0]) + 1;FD_ZERO(&rset);Signal(SIGALRM, recvfrom_alarm);while (Fgets(sendline, MAXLINE, fp) != NULL) {Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);alarm(5);for (; ; ) {FD_SET(sockfd, &rset);FD_SET(pipefd[0], &rset);if ((n = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {if (errno == EINTR)continue;elseerr_sys("select error");}if (FD_ISSET(sockfd, &rset)) {len = servlen;n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);recvline[n] = 0;	/* null terminate */printf("from %s: %s",Sock_ntop_host(preply_addr, len), recvline);}if (FD_ISSET(pipefd[0], &rset)) {Read(pipefd[0], &n, 1);		/* timer expired */break;}}}free(preply_addr);
}static void
recvfrom_alarm(int signo)
{Write(pipefd[1], "", 1);	/* write one null byte to pipe */return;
}
以上知识点来均来自steven先生所著UNP卷一(version3),刚开始学习网络编程,如有不正确之处请大家多多指正。

这篇关于UNP卷一chapter20 广播的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/935631

相关文章

android面试:如何理解 Android 中的广播?

在 Android 中,广播是一种用于在应用程序之间传递消息的机制。它允许应用程序发送和接收全局消息,通常用于通知其他应用或组件某些事件的发生。广播可以是系统广播(由系统发送)或自定义广播(由应用程序发送)。 广播的主要特点: 异步通信:广播是一种异步的通信方式,发送广播的应用不需要等待接收应用的响应。 全局可见:广播可以被系统中的任何应用程序接收,适合用于跨应用的消息传递。 轻量级:广播

Android 接收系统广播,开机启动Service,SMS,Battery

本文内容摘自《疯狂Android讲义 第3版》李刚 著 自动开启的Service: package shortcut.song.com.myapplication;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;im

Android Ordered Broadcast 有序广播

代码设置IntentFilter: IntentFilter intentFilter = new IntentFilter();intentFilter.setPriority(15);intentFilter.addAction("shortcut.song.com.myapplication.MY_BROADCAST");intentFilter.addCategory

Android BroadcastRecevier广播消息

代码注册Receiver @Overrideprotected void onCreate(Bundle savedInstanceState) {IntentFilter intentFilter = new IntentFilter();intentFilter.addAction("");MyBroadcast myBroadcast = new MyBroadcast();regi

2024全球广播摄像机市场前景如何?IP网络化云端融合趋势加强

一、前言 当前,全球广播电视用户持续向流媒体迁移。大多数国家广播电视台推出独立流媒体平台,流媒体趋势日渐加强。与奈飞等非广电系流媒体平台只提供点播服务不同,广电系流媒体平台一般提供电视频道直播服务、电视回看服务、视频点播服务,与传统电视渠道形成互补,而这些流媒体平台与网络媒体平台所能提供的视频服务存在着非常重合的区域。 (1)流媒体时代加速广播摄像机专业影视化发展 全球广电系流媒体平台竞争力

单播、广播、多播

单播、多播和广播单播”(Unicast)、“多播”(Multicast)和“广播”(Broadcast)这三个术语都是用来描述网络节点之间通讯方式的术语。那么这些术语究竟是什么意思?区别何在? 1.单播:网络节点之间的通信就好像是人们之间的对话一样。如果一个人对另外一个人说话,那么用网络技术的术语来描述就是“单播”,此时信息的接收和传递只在两个节点之间进行。单播在网络中得到了广泛的应用,网络上

RocketMQ广播消费消息

1、 基础概念 RocketMQ 支持两种消息模式:集群消费( Clustering )和广播消费( Broadcasting )。 集群消费模式(Cluster): 在集群消费模式下,同一个消费者组(Consumer Group)中的每个消费者都会消费消息的一个副本。消息会被分发到不同的消费者实例上,但是同一个消息只会被同一个消费者组中的一个消费者消费。 广播消费模式(Broadcast)

IOS消息分发(广播)机制

在IOS中,提供了通知机制(Notification),可以在对象间传递和接受信息。传递和接受信息的对象间甚至不需要知道对方的存在。究其本质来说,其实是设计模式中的观察者模式的应用。 通知机制 设想这么一个场景:我开发了一款pdf阅读器,当手机上的另一个App打开pdf文件时,通过Open in,选择我的pdf阅读器打开。这时候我的pdf阅读器会被lanuch,同时在其App deleg

神奇的android广播

最近用了android的广播,个人感觉非常好用: 首先在你要接收的地方注册一个: context.registerReceiver(myReceiver, new IntentFilter("com.shic.action.d")); 然后就是定义注册的这个,在接收到广播后执行的操作: BroadcastReceiver myReceiver = new BroadcastRecei

Android源码解析四大组件系列(八)---广播几个问题的深入理解

接上篇文章,这篇文章主要是总结前面知识,并且了解一些细节问题,加深对广播机制的理解,比如有播有序是怎么保证有序的?广播拦截机制是怎么实现的?广播发送超时了是怎么处理的?registerReceiver方法发返回值有什么用?粘性广播等等。 Android源码解析四大组件系列(五)—广播的注册过程 Android源码解析四大组件系列(六)—广播的处理过程 Android源码解析四大组件系列(七)