一、概述

虽然UDP支持各种形式的地址,但TCP只支持单播地址。

上图要点是:

  • IPv4对多播的支持是可选的,而IPv6则时必须的。
  • IPv6没有提供对广播的支持:当使用广播的IPv4应用程序一直到IPv6时,必须使用IPv6的多播方式进行重新编码。
  • 广播和多播要使用UDP,二者都不能使用TCP

广播的用途:

1.假定服务器主机在本地子网上,但不知道它的单播IP地址时,对它进行定位,这就是资源发现。

2.当有多个客户和单个服务器通信时,减少局域网上数据流量。

常见的实例

1.ARP:ARP是IPv4的一个i额基本组成部分,而不是一个用户应用程序。

2.BOOTP(引导协议,Bootstrap Protocol):客户假定有一台服务器主机在本地子网上。

3.NTP(网络时间协议,Network Timer Protocol):一种常见的情形是:一个NTP客户主机可能配置成使用一个或多个服务器主机IP地址,其上面的NTP客户于是以某个频率轮询这些服务器。

4.路由后台进程。

二、广播地址

如果用{netid,subnetid,hostid}({网络ID,子网ID,主机ID})表示IPv4地址,那么有四种类型的广播地址。

1.子网广播地址:{netid,subnetid,-1}。这类地址编排指定子网上的所有接口。

2.全部子网广播地址:{netid,-1,-1}。这类广播地址编排指定网络上的所有子网。

3.网络广播地址:{netid,-1}。这类地址用于不进行子网划分的网络。

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

三、竞争状态

  多个进程访问共享数据,但正确结果依赖于进程的执行顺序,这种情况我们称之为竞争状态。

竞争状态通常是线程编程中时钟要注意的一个重要问题,因为在线程中有非常多的数据需要共享。

  在进行信号处理时,通常会出现各种类型的竞争状态。这是因为在我们的程序执行过程中,内核随时都会递交信号。

例子1:

 #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 = ;
char sendline[MAXLINE], recvline[MAXLINE+];
sigset_t sigset_alarm;
socklen_t len;
struct sockaddr *preply_addr;
preply_addr = Malloc(servlen);
Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
Sigemptyset(&sigset_alarm);
Signal(SIGALRM, recvfrom_alarm);
while(Fgets(sendline, MAXLINE, fp) != NULL) {
Sendto(sockfd, sendline, strlen(sendline), , pservaddr, servlen);
alarm();
for( ; ;) {
len = servlen;
Sigprocmask(SIG_UNBLOCK, &sigset_alrm, NULL);
n = recvfrom(sockfd, recvline, MAXLINE, , preply_addr, &len);
Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);
if(n < ) {
if(errno == EINTR)
break; /* waited long enough for replies */
else
err_sys("recvfrom error");
} else {
recvline[n] = ; /* null terminate */
printf("from %s: %s", Sock_ntop_host(preply_addr, len), recvline);
}
}
}
} static void
recvfrom_alarm(int signo)
{
return; /* just nterrupt the recvfrom() */
}

example1

解阻塞信号、调用recvfrom和阻塞信号都是互相独立的系统调用。假定recvfrom返回了最后一个应答数据报并且SIGALRM信号在recvfrom和阻塞信号之间递交,下一次recvfrom的调用将永远阻塞。错误

例子2:

#include "unp.h"
#include <setjmp.h>
static void recvfrom_alarm(int);
static sigjmp_buf jmpbuf;
void
dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{
int n;
const int on = ;
char sendline[MAXLINE], recvline[MAXLINE+];
socklen_t len;
struct sockaddr *preply_addr;
preply_addr = Malloc(servlen);
Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
Signal(SIGALRM, recvfrom_alarm);
while(Fgets(sendline, MAXLINE, fp) != NULL) {
Sendto(sockfd, sendline, strlen(sendline), , pservaddr, servlen);
alarm();
for( ; ; ) {
if(sigsetjmp(jmpbuf, ) != )
break;
len = servlen;
n = Recvfrom(sockfd, recvline, MAXLINE, , preply_addr, &len);
recvline[n] = ;
printf("from %s: %s", Sock_ntop_host(preply_addr, len), recvline);
}
}
}
static void
recvfrom_alarm(int signo)
{
siglongjmp(jmpbuf, );
}

example2

pselect的关键点是设置信号掩码、测试描述字及恢复信号掩码等操作都是原子操作。错误

例子3:

#include "unp.h"
static void recvfrom_alarm(int);
static int pipefd[];
void
dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{
int n, maxfdp1;
const int on = ;
char sendline[MAXLINE], recvline[MAXLINE + ];
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);
maxfdp1 = max(sockfd, pipefd[]) + ;
FD_ZERO(&rset);
Signal(SIGALRM, recvfrom_alarm);
while(Fgets(sendline, MAXLINE, fp) != NULL) {
Sendto(sockfd, sendline, strlen(sendline), , pservaddr, servlen);
alarm();
for( ; ; ) {
FD_SET(sockfd, &rset);
FD_SET(pipefd[], &rset);
if((n = select(maxfdp1, &rset, NULL, NULL, NULL)) < ) {
if(errno == EINTR)
continue;
else
err_sys("select error");
}
if(FD_ISSET(sockfd, &rset)) {
len = servlen;
n = Recvfrom(sockfd, recvline, MAXLINE, , preply_addr, &len);
recvline[n] = ;
printf("from %s: %s", Sock_ntop_host(preply_addr, len), recvline);
}
if(FD_ISSET(pipefd[], &rset)) {
Read(pipefd[], &n, );
break;
}
}
}
}
static void
recvfrom_alarm(int signo)
{
Write(pipefd[], "", );
return;
}

example3

另一个解决同一问题的正确方法。不是让信号处理简单的返回,期望这样能够中断被阻塞的rrecvfrom相反,我们让信号黑醋栗程序使用IPC通知dg_cli函数到抵制其到时。

UNP学习 广播的更多相关文章

  1. unp学习笔记——Chapter1

    1.发现网络拓扑的几个重要的命令 (1).netstat -i 提供网络接口的信息.我们还指定-n 标志以输出数值地址,而不是试图把它们反向解析成名字.netstat -r 展示路由表. dzhwen ...

  2. UNP学习笔记(第十五章 UNIX域协议)

    UNIX域协议是在单个主机上执行客户/服务器通信的一种方法 使用UNIX域套接字有以下3个理由: 1.UNIX域套接字往往比通信两端位于同一个主机的TCP套接字快出一倍 2.UNIX域套接字可用于在同 ...

  3. UNP学习笔记(第十四章 高级I/O函数)

    本章讨论我们笼统地归为“高级I/O”的各个函数和技术 套接字超时 有3种方法在涉及套接字的I/O操作上设置超时 1.调用alarm,它在指定超时时期满时产生SIGALRM信号 2.在select中阻塞 ...

  4. UNP学习笔记(第六章 I/O复用)

    I/O模型 首先我们将查看UNIX下可用的5种I/O模型的基本区别: 1.阻塞式I/O 2.非阻塞式I/O 3.I/O复用(select和poll) 4.信号驱动式I/O(SIGIO) 5.异步I/O ...

  5. UNP学习笔记(第五章 TCP客户/服务程序实例)

    我们将在本章使用前一章中介绍的基本函数编写一个完整的TCP客户/服务器程序实例 这个简单得例子是执行如下步骤的一个回射服务器: TCP回射服务器程序 #include "unp.h" ...

  6. UNP学习 多播

    一.概述 单播地址标识单个接口,广播地址标识子网上的所有接口,多播地址标识一组接口. 单播和广播是编址方案的两个极端,多播的目的就在于提供一种折衷的方案. 二.多播地址 我们必须区分IPv4多播地址和 ...

  7. UNP学习总结(二)

    本文是UNP复习系列的第二篇,主要包括了以下几个内容 UNIX系统下5种I/O模型 阻塞.非阻塞,同步.异步 epoll函数用例 一.Unix下的五种可用I/O模型 阻塞式I/O模型 阻塞式I/O是最 ...

  8. UNP学习总结(一)

    本文主要为对UNP第五章部分内容的实验和总结. UNP第五章对一个echo服务器和客户端在各种连接状态下的表现做了详细的分析,包括了: 正常启动和终止: accept返回前连接中止: 服务器进程终止: ...

  9. Android学习--广播机制

    广播机制简介 Android的广播可以分为两种类型的,标准广播和有序的广播: 标准广播:  是一种完全异步执行的广播,在广播发出去之后,所有的广播接收器几乎是同一时接收到这条广播. 有序广播:  是一 ...

随机推荐

  1. HDU 6040 Hints of sd0061 —— 2017 Multi-University Training 1

    Hints of sd0061 Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  2. 【LeetCode 84】柱状图中最大的矩形

    题目链接 [题解] 维护一个单调递增的栈. 会发现栈内的第i个元素的前面一个(i-1)元素在原始的序列中的数字 都是要高于第i个元素的.(或者没有元素) 那么第i个元素往左最多可以扩展到第i-1个元素 ...

  3. C++ 使用STL string 实现的split,trim,replace-修订

    写个小工具函数 #include <iostream> #include <vector> using namespace std; namespace strtool { s ...

  4. ip地址与子网掩码----基础知识

    前言 IP地址有三种基本类型,由网络号的第一组数字来表示. A类地址的第一组数字为1-126. B类地址的第一组数字为128-191. C类地址的第一组数字为192-223. 注:数字0和 127不作 ...

  5. Docker问题方案收集

    1.问题: Unable to connect to unix:///var/run/docker.sock (Permission denied) from PHP code 解决方法: Make ...

  6. php7.0 新增运算符??

    ??是php7 新增符号 其作用近似于三目运算符 ?: 但存在着细微差别 比较示例代码如图:         $b = $a?$a:2; 三目运算 <=>     $e = $a??'ho ...

  7. linux系统中查看日志及系统信息

    cat tail -f 日 志 文 件说 明 /var/log/message系统启动后的信息和错误日志,是Red Hat Linux中最常用的日志之一 /var/log/secure与安全相关的日志 ...

  8. 基于Java Agent的premain方式实现方法耗时监控(转),为了找到结论执行:premain在jvm启动的时候执行,所有方法前,会执行MyAgent的premain方法

    Java Agent是依附于java应用程序并能对其字节码做相关更改的一项技术,它也是一个Jar包,但并不能独立运行,有点像寄生虫的感觉.当今的许多开源工具尤其是监控和诊断工具,很多都是基于Java ...

  9. 用于拆解和组合PDF中各个对象的shell脚本

    拆解脚本 header_start=0 header_len=15 xref_start=$(strings -a -t d $1 | grep -e "\bxref\b" | a ...

  10. PAT甲级【2019年3月考题】——A1157 Anniversary【25】

    Zhejiang University is about to celebrate her 122th anniversary in 2019. To prepare for the celebrat ...