【UNIX网络编程】广播与多播

前言

继续补上我的博客,这几天专注把【UNIX网络编程】的内容总结。

1.单播与广播的比较

单播 过程:


中间主机的以太网接口看到该帧,并将它的目的以太网与自己的以太网地址进行比较。由于二者不相等,接口便忽略该帧。因此,单播帧不会对这台主机造成任何额外开销,因为忽略它们的是接口而不是主机。

右边主机的以太网接口也看到该帧。并将它的目的以太网与自己的以太网地址进行比较。发现二者相等,接口便读入该帧。

广播过程:


 左边的主机发送的是广播数据报,其地址为128.7.6.255,当左边的主机发送数据报时,它注意到目的IP地址是子网广播地址,于是便将它映射成48位的以太网地址:ff.ff.ff.ff.ff.ff。这使得子网上的每一个以太网接口都会接收该帧。

        由于是广播类型的数据报,右侧的两台主机都将数据报传递到IP层。但是由于中间的主机没有任何应用进程绑定相应的UDP端口,于是主机的UDP代码丢弃这个已收到的数据报。

        以上的例子表明了广播存在一个根本问题:子网上所有未参与广播应用系统的主机也必须完成对数据报的协议处理,直至在UDP层将它丢弃。因此以高速率产生IP数据报的应用系统(例如音频、视频应用程序)会严重影响子网上其他主机的运行,而这类型的应用程序应该采用多播技术来解决该问题。

20.4中的例子

图20-5中使用广播技术的回射客户程序,使用广播地址把输入的字符串发送给子网里所有的主机,设置了broadcast选项。

setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
不过在我自己的主机上运行时发现,不设置此项同样可以运行,这一点应该和各个内核实现有关,为了有更加优良的移植性,最好还是加上这一段代码。

2.竞争状态

什么是竞争状态:

此处所说的竞争状态主要是针对UNIX系统中的信号来说的,在系统运行的过程中,如果某个函数调用会阻塞,并且打算使用UNIX信号(比如SIGALRM定时)来中断这个调用,那么就有可能遇上别的函数调用的时候,这个信号产生了,没能成功的在阻塞函数调用时候中断。这就是竞争状态。

在UNP书中,这里是希望使用SIGALRM信号来中断阻塞的recvfrom调用,但是由于未考虑如果SIGALRM信号产生时未能中断recvfrom函数的情况,因此可能会一直阻塞在recvfrom函数中。

解决方法:

1. 使用片pselect阻塞和解阻塞信号

做法是:

a.调用

sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);
b.调研pselect函数,该函数在阻塞阶段将保存之前的信号掩码,并设置成现在的掩码

pselect(sockfd+1, &rset, NULL, NULL, NULL, &segset_empty);
c. 在pseelect阻塞时,信号是可以递交的,但单pselect返回了之后,又会恢复到之前阻塞信号的掩码,因此,此时信号是不可以中断函数调用的。

2.使用sigsetjmp和siglongjmp

siglongjmp可以从一个函数转跳到另一个函数中,称为“非局部转跳”

a.先调用sigsetjmp建立转跳缓冲区然后返回0

if( sigsetjmp(jmpbuf, 1) !=0)
<span style="white-space:pre">	</span>break;
在信号来临时,在中断函数里调用siglongjmp

siglongjmp(sigbuf, 1);
这样会导致上面的sigsetjmp函数返回1.然后调用break;

3.使用IPC(Inter-Process Communication,进程间通信 方式
a.建立一个管道

<span style="white-space:pre">	</span>int pipefd[2];
<span style="white-space:pre">	</span>pipe(pipefd);
b.使用select测试套接字和管道
<span style="white-space:pre">	</span>FD_SET(sockfd, &rset);
<span style="white-space:pre">	</span>FD_SET(pipefd[0], &rset);
<span style="white-space:pre">	</span>select(maxfdp1, &rset, NULL, NULL, NULL);
c.在中断函数中网管道中写入一个字,因此pipefd将会变成可读,避免了竞争。


总结
竞争问题的产生还是由于使用了UNIX信号,想让信号中断在理想的地方时很难的,因此只能使用通知主进程的方式。

所以IPC方法和select阻塞,我觉得是最方便且合适的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 封面 -12 封底 -11 扉页 -10 版权 -9 版权声明 -8 前言 -7 目录 -3 第一部分 简介 1 第1章 简介 2 1.1 概述 2 1.2 进程、线程与信息共享 3 1.3 IPC对象的持续性 4 1.4 名字空间 5 1.5 fork、exec和exit对IPC对象的影响 7 1.6 出错处理:包裹函数 8 1.7 Unix标准 9 1.8 书中IPC例子索引表 11 1.9 小结 13 习题 13 第2章 Posix IPC 14 2.1 概述 14 2.2 IPC名字 14 2.3 创建与打开IPC通道 16 2.4 IPC权限 18 2.5 小结 19 习题 19 第3章 System V IPC 20 3.1 概述 20 3.2 key_t键和ftok函数 20 3.3 ipc_perm结构 22 3.4 创建与打开IPC通道 22 3.5 IPC权限 24 3.6 标识符重用 25 3.7 ipcs和ipcrm程序 27 3.8 内核限制 27 3.9 小结 28 习题 29 第二部分 消息传递 31 第4章 管道和FIFO 32 4.1 概述 32 4.2 一个简单的客户-服务器例子 32 4.3 管道 32 4.4 全双工管道 37 4.5 popen和pclose函数 39 4.6 FIFO 40 4.7 管道和FIFO的额外属性 44 4.8 单个服务器,多个客户 46 4.9 对比迭代服务器与并发服务器 50 4.10 字节流与消息 51 4.11 管道和FIFO限制 55 4.12 小结 56 习题 57 第5章 Posix消息队列 58 5.1 概述 58 5.2 mq_open、mq_close和mq_unlink函数 59 5.3 mq_getattr和mq_setattr函数 61 5.4 mq_send和mq_receive函数 64 5.5 消息队列限制 67 5.6 mq_notify函数 68 5.7 Posix实时信号 78 5.8 使用内存映射I/O实现Posix消息队列 85 5.9 小结 101 习题 101 第6章 System V消息队列 103 6.1 概述 103 6.2 msgget函数 104 6.3 msgsnd函数 104 6.4 msgrcv函数 105 6.5 msgctl函数 106 6.6 简单的程序 107 6.7 客户-服务器例子 112 6.8 复用消息 113 6.9 消息队列上使用select和poll 121 6.10 消息队列限制 122 6.11 小结 124 习题 124 第三部分 同步 125 第7章 互斥锁和条件变量 126 7.1 概述 126 7.2 互斥锁:上锁与解锁 126 7.3 生产者-消费者问题 127 7.4 对比上锁与等待 131 7.5 条件变量:等待与信号发送 132 7.6 条件变量:定时等待和广播 136 7.7 互斥锁和条件变量的属性 136 7.8 小结 139 习题 139 第8章 读写锁 140 8.1 概述 140 8.2 获取与释放读写锁 140 8.3 读写锁属性 141 8.4 使用互斥锁和条件变量实现读写锁 142 8.5 线程取消 148 8.6 小结 153 习题 153 第9章 记录上锁 154 9.1 概述 154 9.2 对比记录上锁与文件上锁 157 9.3 Posix fcntl记录上锁 158 9.4 劝告性上锁 162 9.5 强制性上锁 164 9.6 读出者和写入者的优先级 166 9.7 启动一个守护进程的唯一副本 170 9.8 文件作锁用 171 9.9 NFS上锁 173 9.10 小结 173 习题 174 第10章 Posix信号量 175 10.1 概述 175 10.2 sem_open、sem_close和sem_unlink函数 179 10.3 sem_wait和sem_trywait函数 180 10.4 sem_post和sem_getvalue函数 180 10.5 简单的程序 181 10.6 生产者-消费者问题 186 10.7 文件上锁 190 10.8 sem_init和sem_destroy函数 191 10

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值