3. 广播的介绍

(1)广播

  ①广播实现一对多的通信,如QQ群

  ②它通过向广播地址发送数据报文实现的

(2)SO_BROADCAST选项

  ①SO_BROADCAST选项控制着UDP套接字是否能发送广播数据报,选项的类型为int,非零意味着“是”。

  ②注意,该选项只有UDP套接字可以使用,TCP是不能使用广播的

(3)其它选项:SO_SNDBUFSO_RCVBUF选项

  ①每一个套接字有一个发送缓冲区和接收缓冲区,这两个缓冲区由底层协议使用。

  ②接收缓冲区存放由协议接收的数据直到被应用程序读走发送缓冲区存放应用写出的数据直接被协议发送出去

  ③SO_SNDBUF和SO_RCVBUF选项分别控制发送和接收缓冲区的大小,他们的类型均为int,以字节为单位。

(4)广播地址

  ①如果用{netID, subnetID, hostID}来表示IPv4地址,那么有四类的广播地址,用-1表示所有比特都为1的字段。

  ②子网广播地址:{netID, subnetID, -1}。这类地址编排指定子网上的所有接口。例如,如果我们对C类地址192.168采用8位子网ID,那么192.168.2.255将是192.168.2子网上所有接口的子网广播地址路由器通常不转发这类广播

  ③全部子网广播地址{netID,-1,-1}。这类广播地址编排指定网络上的所有子网。现在很少这样用。

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

【编程实验】利用UDP发送广播(多对多或一对多)

//receiver.c

#include <netdb.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <memory.h> int sockfd; void sig_handler(int signo)
{
if(signo == SIGINT){
printf("receiver will exit\n");
close(sockfd);
exit();
}
} int main(int argc, char* argv[])
{
if(argc < ){
fprintf(stderr, "usage: %s port\n", argv[]);
exit();
} if(signal(SIGINT, sig_handler) == SIG_ERR){
perror("signal sigint error");
exit();
} //创建套接字
sockfd = socket(AF_INET, SOCK_DGRAM, ); //UDP协议
if(sockfd < ){
perror("socket error");
exit();
} //绑定地址,以便在指定的端口上接收广播
struct sockaddr_in recvAddr;
memset(&recvAddr, , sizeof(recvAddr));
recvAddr.sin_family = AF_INET; //IPv4
recvAddr.sin_port = htons(atoi(argv[])); //port
recvAddr.sin_addr.s_addr = INADDR_ANY; //由系统指定IP if(bind(sockfd, (struct sockaddr*)&recvAddr, sizeof(recvAddr)) < ){
perror("bind error");
exit();
} //接收广播消息
char buff[];
struct sockaddr_in sendAddr;
socklen_t len = sizeof(sendAddr);
while(){
memset(buff, , sizeof(buff));
memset(&sendAddr, , sizeof(sendAddr));
if(recvfrom(sockfd, buff, sizeof(buff), , (struct sockaddr*)&sendAddr, &len) < ){
perror("recvfrom error");
exit();
}else{
char ip[];
inet_ntop(AF_INET, &sendAddr.sin_addr.s_addr, ip, sizeof(ip));
int port = ntohs(sendAddr.sin_port);
printf("%s(%d): %s\n", ip, port, buff);
} }
}
/*输出结果
[root@localhost 14.udp]# gcc -o bin/broadcast src/broadcast.c
[root@localhost 14.udp]# bin/receiver
usage: bin/receiver port
[root@localhost 14.udp]# bin/receiver 8888
192.168.32.100(40894): hello world!
192.168.32.100(33915): hello world!
192.168.32.100(48427): hello world!
^Creceiver will exit
*/

//broadcast.c

#include <netdb.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h> int main(int argc, char* argv[])
{
if(argc < ){
fprintf(stderr, "usage: %s ip port\n", argv[]);
exit();
} //创建套接字
int sockfd = socket(AF_INET, SOCK_DGRAM, ); //UDP协议
if(sockfd < ){
perror("socket error");
exit();
} //设置为广播方式发送消息
int opt = ;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)); struct sockaddr_in recvAddr; //指定广播的接收者地址信息。
memset(&recvAddr, , sizeof(recvAddr));
recvAddr.sin_family = AF_INET;
recvAddr.sin_port = htons(atoi(argv[])); //注意,不指定IP(广播为255),只说明接收者的端口
inet_pton(AF_INET, argv[], &recvAddr.sin_addr.s_addr); printf("I will broadcast...\n");
char* info = "hello world!";
size_t size = strlen(info)* sizeof(char);
if(sendto(sockfd, info, size, , (struct sockaddr*)&recvAddr, sizeof(recvAddr)) < ){
perror("sendto error");
exit();
}else{
printf("broadcast success\n");
} close(sockfd); return ;
}
/*输出结果
* [root@localhost 14.udp]# bin/broadcast 192.168.32.100 8888
* I will broadcast...
* broadcast success
* [root@localhost 14.udp]# bin/broadcast 192.168.32.100 8888
* I will broadcast...
* broadcast success
* [root@localhost 14.udp]# bin/broadcast 192.168.32.100 8888
* I will broadcast...
* broadcast success
*/

第14章 UDP编程(3)_利用UDP实现广播功能的更多相关文章

  1. 第14章 UDP编程(1)_UDP客户端服务器模型

    1. UDP编程模型 (1)UDP客户端服务器模型 ①客户端可以不调用bind()而直接与服务器通讯. ②UDP是无连接的,因此服务端不需要调用accept和listen,客户端也无需调用connec ...

  2. Twisted UDP编程技术

    实战演练1:普通UDP UDP是一种无连接对等通信协议,没有服务器和客户端概念,通信的任何一方均可通过通信原语直接和其他方通信 1.相对于TCP,UDP编程只需定义DatagramProtocol子类 ...

  3. Socket编程实践(12) --UDP编程基础

    UDP特点 无连接,面向数据报(基于消息,不会粘包)的传输数据服务; 不可靠(可能会丢包, 乱序, 反复), 但因此普通情况下UDP更加高效; UDP客户/服务器模型 UDP-API使用 #inclu ...

  4. udp编程中,一次能发送多少个bytes为好?

    在进行UDP编程的时候,我们最容易想到的问题就是,一次发送多少bytes好? 当然,这个没有唯一答案,相对于不同的系统,不同的要求,其得到的答案是不一样的,我这里仅对    像ICQ一类的发送聊天消息 ...

  5. 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化

    第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...

  6. 【机器学习实战】第14章 利用SVD简化数据

    第14章 利用SVD简化数据 SVD 概述 奇异值分解(SVD, Singular Value Decomposition): 提取信息的一种方法,可以把 SVD 看成是从噪声数据中抽取相关特征.从生 ...

  7. 老李推荐:第14章1节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-面向控件编程VS面向坐标编程

    老李推荐:第14章1节<MonkeyRunner源码剖析> HierarchyViewer实现原理-面向控件编程VS面向坐标编程   poptest是国内唯一一家培养测试开发工程师的培训机 ...

  8. 《mysql必知必会》学习_第14章_20180806_欢

    第14章:使用子查询. 子查询是镶嵌在其他查询里面,相当其他的select查询的条件来. P91 select order_num from where prod_id='tnt2';   #检索条件 ...

  9. Windows核心编程:第14章 探索虚拟内存

    Github https://github.com/gongluck/Windows-Core-Program.git //第14章 探索虚拟内存.cpp: 定义应用程序的入口点. // #inclu ...

随机推荐

  1. ThreadLocal讲解

    一.前言 ThreadLocal这个对象就是为多线程而生的,没有了多线程ThreadLocal就没有存在的必要了.可以将任何你想在每个线程独享的对象放置其中,并在任何时候取出来. 二.基本用法 Thr ...

  2. OVSSL企业证书认证

    最近,在做http->https的转化,虽然我没有操作证书的安装过程,但是在这个过程中学习到不少知识呢. 因为我没有操作,所以操作上我就不知道了.下面是这个过程中要注意的一些事项: 1.公司名称 ...

  3. Java8函数式编程学习笔记(初探)

    编程语言的整个目的就在于操作值,要是按照历史上编程语言的传统,这些值被成为一等值,而编程语言中的其他结构也许有助于表示值的结构,但在程序执行期间不能传递,因此为二等值,比如方法和类等则是二等值,类可以 ...

  4. java8 array、list操作 汇【4】)- Java8 Lambda表达式 函数式编程

    int tmp1 = 1; //包围类的成员变量 static int tmp2 = 2; //包围类的静态成员变量 //https://blog.csdn.net/chengwangbaiko/ar ...

  5. 【Quartz】Quartz将Job保存在数据库中所需表的说明

    QRTZ_CALENDARS 以 Blob 类型存储 Quartz 的 Calendar 信息 QRTZ_CRON_TRIGGERS 存储 Cron Trigger,包括 Cron表达式和时区信息  ...

  6. day 2Linux软件从主机安装到服务器和安装JDK软件

    软件安装 1.如何上传安装包到服务器**可以使用图形化工具,如: filezilla**可以使用sftp工具: alt+p 调出后,用put命令上传上传(如果不cd指定目录,则上传到当前用户的主目录) ...

  7. 内核启动卡在 Starting kernel ...

    一.有时log是这样的 Card did not respond to voltage select! bytes read ms (39.8 MiB/s) bytes read ms (13.4 M ...

  8. mysql 变量名称的使用不当的一个错误

    对于开发来说重要的是按照规范进行开发. 昨天自己在进行开发测试的时候,编写mysql 的一个存储过程 ,代码是比较简单的 就是根据名称查询对应的数据并返回 DELIMITER // CREATE PR ...

  9. nyoj 单调递增最长子序列

    单调递增最长子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 求一个字符串的最长递增子序列的长度如:dabdbf最长递增子序列就是abdf,长度为4   输入 ...

  10. OAuth 2.0:Bearer Token、MAC Token区别

    Access Token 类型介绍 介绍两种类型的Access Token:Bearer类型和MAC类型 区别项 Bearer Token MAC Token 1 (优点) 调用简单,不需要对请求进行 ...