UNP卷1:第二十章(广播)
来源:互联网 发布:淘宝 内容质量分 优质 编辑:程序博客网 时间:2024/04/26 14:52
1. 单播和广播的比较
UDP数据报单播示例:
1. 通过ARP将IP地址转换为目的以太网地址:00:0a:95:79:bc:b4
2. 中间主机的以太网接口看到该帧后把它的目的以太网地址与自己的以太网地址(00:04:ac:17:bf:38)进行比较。既然它们不一致,该接口于是忽略这个帧。可见单播帧不会对该主机造成任何额外开销,因为忽略它们的是接口而不是主机。
3. 右侧主机的以太网接口也看到这个帧,当它比较该帧的目的以太网地址和自己的以太网地址时,会发现它们相同。该接口于是读入整个帧,读入完毕后可能产生一个硬件中断,致使相应设备驱动程序从接口内存中读取该帧。既然该帧类型为0x8000,该帧承载的分组于是被置于IP的输入队列。
单播IP数据报仅通过目的IP地址指定的单个主机接收。子网上的其他主机都不受任何影响。
UDP数据报广播示例
1. 左侧主机发送该数据报时候发现,IP地址定向为广播地址,则将此IP映射为:ff:ff:ff:ff:ff:ff的以太网地址。这个地址使得该子网上的每一个以太网接口都接收该帧。
2. 右侧的那个主机把该UDP数据报传递给绑定端口520的应用进程。一个应用进程无需就为接收广播UDP数据报而进行任何特殊处理:它只需要创建一个UDP套接字,并把应用的端口号捆绑到其上。
3. 然而中间的那个主机没有任何应用进程绑定UDP端口520.该主机的UDP代码于是丢弃这个已收取的数据报。该主机绝不能发送一个ICMP端口不可达消息,因为这么做可能产生广播风暴,即子网上大量主机几乎同时产生一个响应,导致网络在这段时间内不可用。
4. 左侧主机的数据报也被传递给自己。
广播存在的根本问题:
子网上未参加相应广播应用的所有主机也不得不沿着协议栈一路向上完整的处理收取的UDP广播数据报,直到该数据报历经UDP层时被丢弃为止。另外,子网上所有非IP的主机也不得不在数据链路层街搜完整的帧,然后在丢弃它。
广播实例1:
tserv.c:
#include <sys/socket.h>#include <stdio.h>#include <netinet/in.h>#include <time.h>#define MAXLINE 1024#define SA struct sockaddrint main(int argc, char **argv){struct sockaddr_insrvaddr;intsockfd, on = 1;intnum, i;time_tticks;charmesg[MAXLINE + 1];if (argc != 3){printf("usage:%s<ip address><port>\n", argv[0]);exit(0);}sockfd = socket(AF_INET, SOCK_DGRAM, 0);setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(int));bzero(&srvaddr, sizeof(srvaddr));srvaddr.sin_family = AF_INET;if (inet_pton(AF_INET, argv[1], &srvaddr.sin_addr) <= 0){printf("wrong dest ip address\n");exit(0);}srvaddr.sin_port = htons(atoi(argv[2]));for ( ; ; ){ticks = time(NULL);snprintf(mesg, sizeof(mesg), "%.24s\r\n", ctime(&ticks));sendto(sockfd, mesg, strlen(mesg), 0, (SA *)&srvaddr, sizeof(srvaddr));sleep(5);}return 0;}
tcli.c:
#include <sys/socket.h>#include <stdio.h>#include <netinet/in.h>#include <sys/types.h>#define MAXLINE 1024#define SA struct sockaddrint main(int argc, char **argv){struct sockaddr_incliaddr;intsockfd, n, opt;charmesg[MAXLINE + 1];if (argc != 2){printf("usage:%s<port>\n", argv[1]);exit(0);}sockfd = socket(AF_INET, SOCK_DGRAM, 0);bzero(&cliaddr, sizeof(cliaddr));cliaddr.sin_port = htons(atoi(argv[1]));cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);opt = SO_REUSEADDR;setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));bind(sockfd, (SA *)&cliaddr, sizeof(cliaddr));n = read(sockfd, mesg, MAXLINE);if (n > 0){mesg[n] = 0;printf("%s\n", mesg);}return 0;}
程序输出:
服务端:
leichaojian@ThinkPad-T430i:~$ ./tserv 192.168.0.255 9876客户端1:
leichaojian@ThinkPad-T430i:~$ ./tcli 9876Tue Oct 14 20:40:43 2014客户端2:
leichaojian@ThinkPad-T430i:~$ ./tcli 9876Tue Oct 14 20:40:53 2014
广播实例2:
bcastsrv.c:
#include <sys/socket.h>#include <signal.h>#include <stdio.h>#include <netinet/in.h>#include <time.h>#include <errno.h>extern int errno;#define MAXLINE 1024#define SA struct sockaddrstatic void recvfrom_alarm(int signo);void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen);int main(int argc, char **argv){struct sockaddr_insrvaddr;intsockfd, on = 1;intn;charmesg[MAXLINE + 1];if (argc != 3){printf("usage:%s<ip addr><port>\n", argv[0]);exit(0);}sockfd = socket(AF_INET, SOCK_DGRAM, 0);bzero(&srvaddr,sizeof(srvaddr));srvaddr.sin_family = AF_INET;inet_pton(AF_INET, argv[1], &srvaddr.sin_addr);srvaddr.sin_port = htons(atoi(argv[2]));dg_cli(stdin, sockfd, (SA *)&srvaddr, sizeof(srvaddr));return 0;}static void recvfrom_alarm(int signo){return;}void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen){intn;constint on = 1;charsendline[MAXLINE], recvline[MAXLINE + 1];socklen_tlen;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), 0, pservaddr, servlen);//alarm(3);//for ( ; ; ){len = servlen;n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);if (n < 0){if (errno == EINTR)break;elseprintf("recvfrom error\n");} else{recvline[n] = 0;inet_ntop(AF_INET, &preply_addr, sendline, sizeof(sendline));printf("from %s:%s\n", sendline, recvline);}//}}free(preply_addr);}
bcastcli.c:
#include <stdio.h>#include <sys/socket.h>#include <sys/types.h>#include <time.h>#include <netinet/in.h>#define MAXLINE 1024#define SA struct sockaddrint main(int argc, char **argv){struct sockaddr_incliaddr;intsockfd, n, len;charmesg[MAXLINE];time_tticks;if (argc != 2){printf("usage:%s<port>\n", argv[0]);exit(0);}sockfd = socket(AF_INET, SOCK_DGRAM, 0);bzero(&cliaddr, sizeof(cliaddr));cliaddr.sin_port = htons(atoi(argv[1]));cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);cliaddr.sin_family = AF_INET;bind(sockfd, (SA *)&cliaddr, sizeof(cliaddr));for ( ; ; ){len = sizeof(cliaddr);n = recvfrom(sockfd, mesg, MAXLINE, 0, (SA *)&cliaddr, &len);if (n < 0){//sleep(5);continue;}mesg[n] = 0;printf("recv: %s\n", mesg);ticks = time(NULL);snprintf(mesg, sizeof(mesg), "%.24s", ctime(&ticks));sendto(sockfd, mesg, 2424, 0, (SA *)&cliaddr, len);}return 0;}
服务端:
leichaojian@ThinkPad-T430i:~$ ./bcastsrv 192.168.0.255 9876hellofrom 16.224.187.0:Tue Oct 14 21:45:38 2014whatfrom 16.224.187.0:Tue Oct 14 21:45:43 2014hafrom 16.224.187.0:Tue Oct 14 21:45:47 2014
客户端:
leichaojian@ThinkPad-T430i:~$ ./bcastcli 9876recv: hellorecv: whatrecv: ha
- UNP卷1:第二十章(广播)
- UNP卷1:第八章(基本UNP套接字编程)
- UNP卷1:第三章(套接字编程简介)
- UNP卷1:第十一章(名字与地址转换)
- UNP卷1:第十四章(高级I/O函数)
- UNP卷1:第十五章(unix域协议)
- UNIX网络编程卷一:第二十章 广播
- UNP卷1:第一章(简介)
- UNP卷1:第四章(基本TCP套接字编程)
- UNP卷1:第五章(TCP客户/服务器程序示例)
- UNP卷1:第十三章(守护进程和inetd超级服务器)
- unp卷一 第一章~第六章
- UNP(卷2:进程间通信)—— 第4章:管道和FIFO
- UNP(卷2:进程间通信)—— 第5章:Posix消息队列
- UNP(卷2:进程间通信)—— 第6章:System V消息队列
- UNP(卷2:进程间通信)—— 第10章:Posix信号量
- UNP(卷2:进程间通信)—— 第11章:System V 信号量
- UNP(卷2:进程间通信)—— 第12章:共享内存区介绍
- C语言常见字符串面试题
- Java IO 的使用方法
- 15条SQLite3语句
- 使Gallery时设置居左显示
- [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(下)
- UNP卷1:第二十章(广播)
- 给出一个整数N要求出一个最小正整数Q,使其各个数字的乘积正好等于N
- Sum nyoj 欧拉定理简单运用(数论入门)
- javascript简单效果--字体初始位置移动到指定位置
- 批处理命令之Start的详细用法-P处理打开IE窗口最大化
- 程序员是不是应该加强运动?(知乎同名问题)
- 圆形领域LBP特征
- NetCat
- 网络加载图片的三种方法