第14章 UDP编程(3)_利用UDP实现广播功能
3. 广播的介绍
(1)广播
①广播实现一对多的通信,如QQ群
②它通过向广播地址发送数据报文实现的
(2)SO_BROADCAST选项
①SO_BROADCAST选项控制着UDP套接字是否能发送广播数据报,选项的类型为int,非零意味着“是”。
②注意,该选项只有UDP套接字可以使用,TCP是不能使用广播的。
(3)其它选项:SO_SNDBUF和SO_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实现广播功能的更多相关文章
- 第14章 UDP编程(1)_UDP客户端服务器模型
1. UDP编程模型 (1)UDP客户端服务器模型 ①客户端可以不调用bind()而直接与服务器通讯. ②UDP是无连接的,因此服务端不需要调用accept和listen,客户端也无需调用connec ...
- Twisted UDP编程技术
实战演练1:普通UDP UDP是一种无连接对等通信协议,没有服务器和客户端概念,通信的任何一方均可通过通信原语直接和其他方通信 1.相对于TCP,UDP编程只需定义DatagramProtocol子类 ...
- Socket编程实践(12) --UDP编程基础
UDP特点 无连接,面向数据报(基于消息,不会粘包)的传输数据服务; 不可靠(可能会丢包, 乱序, 反复), 但因此普通情况下UDP更加高效; UDP客户/服务器模型 UDP-API使用 #inclu ...
- udp编程中,一次能发送多少个bytes为好?
在进行UDP编程的时候,我们最容易想到的问题就是,一次发送多少bytes好? 当然,这个没有唯一答案,相对于不同的系统,不同的要求,其得到的答案是不一样的,我这里仅对 像ICQ一类的发送聊天消息 ...
- 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化
第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...
- 【机器学习实战】第14章 利用SVD简化数据
第14章 利用SVD简化数据 SVD 概述 奇异值分解(SVD, Singular Value Decomposition): 提取信息的一种方法,可以把 SVD 看成是从噪声数据中抽取相关特征.从生 ...
- 老李推荐:第14章1节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-面向控件编程VS面向坐标编程
老李推荐:第14章1节<MonkeyRunner源码剖析> HierarchyViewer实现原理-面向控件编程VS面向坐标编程 poptest是国内唯一一家培养测试开发工程师的培训机 ...
- 《mysql必知必会》学习_第14章_20180806_欢
第14章:使用子查询. 子查询是镶嵌在其他查询里面,相当其他的select查询的条件来. P91 select order_num from where prod_id='tnt2'; #检索条件 ...
- Windows核心编程:第14章 探索虚拟内存
Github https://github.com/gongluck/Windows-Core-Program.git //第14章 探索虚拟内存.cpp: 定义应用程序的入口点. // #inclu ...
随机推荐
- Python 文件路径
# 文件路径: # 1. 相对路径: 相对于当前程序所在的文件夹, 如果在文件夹内, 随便找, 直接写名字 # 如果不在这个文件夹内, 可能需要出文件夹或者进文件夹 # 出文件夹 ../ # 进文件夹 ...
- <div class="clear"></div>
<div class="clear"></div> 这里的clear是样式名.样式写在CSS文件中 从名称来看估计你的样式为:.clear {clear:b ...
- 了解dto概念,什么是DTO
了解dto概念 此博文收集整理了一些主流的文章对于DTO模式的解读,他们大体相似而又各有所不同.对于设计模式的解读也是一个仁者见仁智者见智的事情,不过设计模式往往都是前辈们在遇到一类特定的问题下而 ...
- 轻松玩转AI 与PDF文件的转化(完美解决字体问题)
经过漫长而坚苦卓绝的研究查阅了网上无数资料下载了众多相关软件进行试验终于,找到搞定PDF文件的方便并且有效的办法PDF文件!你这个魔鬼!退去吧!!!! 难点一: 如何修改客户常常会提供不知道从哪里搞来 ...
- CentOS7使用打开关闭防火墙与端口
systemctl是CentOS7的服务管理工具中主要的工具,它融合之前service和chkconfig的功能于一体. 启动一个服务:systemctl start firewalld.servic ...
- 51Nod1526 分配笔名
分析 在trie树上贪心,将所有串加入trie树中,在深度较深的地方匹配会更优. 由于只需要知道最后的总质量,所以直接取每个点的子树中最大的匹配即可 复杂度\(O(\sum len)\) 加串的时候把 ...
- (考研)散列表和hashcode和hashmap
package tt; import java.util.HashMap; import java.util.Map; public class a0 { public static void mai ...
- hasura graphql server 集成gitlab
默认官方是提供了gitlab 集成的demo的,但是因为gitlab 一些版本的问题, 跑起来总有问题,所以查找相关资料测试了一个可以运行的版本 项目使用docker-compose 运行 参考 ht ...
- 使用gitblit搭建一个简单的局域网服务器
使用gitblit搭建一个简单的局域网服务器 1.使用背景 现在很多使用github管理代码,但是github需要互联网的支持,而且私有的git库需要收费.有一些项目的代码不能外泄,所以,搭建一个局域 ...
- sqlserver中numeric字段截取
方法一:convert(float,字段名) as 别名 select convert(float,round(10.123232,2)) 结果:10.12 select convert(float, ...