一、概述

虽然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. 线程join方法demo-模拟叫号看病

    package cn.chapter4.test5; public class SicknessDemo { /** * 模拟叫号看病 * @param args * * 思路:把普通号看病写在主线程 ...

  2. http 换成 https

    UPDATE SYS_MENU M SET M.href = ( SELECT CASE WHEN substr(N.href, 0, 5) = 'http:' THEN 'https:'||subs ...

  3. @encode关键字

    @encode() 为了更好的互操作性,Objective-C 的数据类型,甚至自定义类型.函数或方法的元类型,都可以使用 ASCII 编码.@encode(aType) 可以返回该类型的 C 字符串 ...

  4. LintCode之删除排序链表中的重复元素

    题目描述: 我的代码: /** * Definition for ListNode * public class ListNode { * int val; * ListNode next; * Li ...

  5. 大数据学习笔记之Hadoop(二):HDFS文件系统

    文章目录 一 HDFS概念 1.1 概念 1.2 组成 1.3 HDFS 文件块大小 二 HFDS命令行操作 三 HDFS客户端操作 3.1 eclipse环境准备 3.1.1 jar包准备 3.2 ...

  6. 工控PLC中,关于定时器TON,TOF,的一点新认知,或者说醒悟吧!

    PLC  中的定时器,都是放在一个具体PRG任务单元中的,而PRG单元需要放在具体固定的周期循环任务中才能被执行,而这个周期循环任务的循环周期 T: 与定时器的定时时间T0:    T与T0 的数量级 ...

  7. Cocos2d Box2D之浮动刚体

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. b2_kinematicBody 运动学物体在模拟环境中根据自身的速度进行移动.运动学物体自身不受力的作用.虽然用户可以手动移动它,但是通 ...

  8. VC++DLL动态链接库程序

    VC++DLL动态链接库程序 VC++DLL动态链接库程序 C++ DLL 导出函数 使用VS2017等IDE生成dll程序,示例如下: C++ DLL 导出类 1.导出类中第一种方法:简单导出类(不 ...

  9. Python 2 将死,你准备好了吗?

    Python 软件基金会宣布,到 2020 年元旦,将不再为编程语言 Python 2.x 分支提供任何支持.这一天将标志着一出延续多年的戏剧的高潮:Python 从较旧的.功能较弱的.广泛使用的版本 ...

  10. ---搭建springMvc框架,希望对初学者有所参考

    Spring Mvc ==> Struts2   spring 无法替代   myBatis 工作量大 要自己操作sql语句 ==> hibernate   Spring Mvc 取代St ...