目录
1. 广播的定义
2. 广播地址的分类
3. 广播的特点
4. 广播的使用
1. 广播的定义
所谓的广播,其实就是一台主机向主机所在的所有子网内的所有主机发送数据的方式。
2. 广播地址的分类
广播地址是一种特殊的IP地址形式,一种是直接广播地址,一种是有限广播地址。
受限广播就是255.255.255.255
受限广播可以用在计算机不知道自己IP地址的时候,比如向DHCP服务器索要地址时、PPPOE拨号时等。
此地址可以在本网络内广播,路由器不允许通过它,所以“受限”。
直接广播就是类似192.168.1.255/24这样的地址
直接广播可用于本地网络,也可以跨网段广播,比如主机192.168.1.1/30可以发送广播包到192.168.1.7,使主机192.168.1.5/30也可以接收到该数据包,前提是之间的路由器要开启定向广播功能.
直接广播地址是允许通过路由器的,当然不是所有的路由器,傻瓜式路由器是默认阻止直接广播的。
3. 广播的特点
首先广播只能用UDP或原始IP实现,不能用TCP
而且,处于同一个子网的所有主机都必须处理数据。UDP数据包会沿着协议栈一直到UDP层,到了UDP层之后只有当端口不匹配时,数据才会丢弃。
4. 广播的使用
默认的情况下,不允许发送广播数据包,需要修改套接口选项:
int setsockopt(int sockfd,
int level,
int optname,
const void *optval,
socklen_t optlen);
- sockfd 套接字描述符
- level 套接字类型
- SOL_SOCKET 基本套接口
- IPPROTO_IP IPv4套接口
- IPPROTO_IPV6 IPv6套接口
- IPPROTO_TCP TCP套接口
optname 其实就是套接字类型对应的选项
如SOL_SOCKET有三个选项:
- SO_BROADCAST 允许发送广播数据包
- SO_RCVBUF 接收缓存区大小
- SO_SNDBUF 发送缓存区大小
- optval 选项对应的值
- optlen 选项对应值的长度
如果成功返回0,否则返回-1
下面我们写一个 UDP 广播发送数据包例子,目的端口指定为 8000,目的 IP 为受限广播地址:255.255.255.255,那样,同一个局域网的所有主机网卡都会收到这个数据,但是,只有端口为 8000 的网络应用程序才会收到这个数据包:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, charchar *argv[])
{
unsigned short port = 8000; // 端口
charchar *server_ip = "255.255.255.255"; // 受限广播地址
int sockfd;
sockfd = socket(AF_INET, SOCK_DGRAM, 0); //创建UDP套接字
if(sockfd < 0)
{
perror("socket");
exit(-1);
}
struct sockaddr_in dest_addr;
bzero(&dest_addr, sizeof(dest_addr));
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(port);
inet_pton(AF_INET, server_ip, &dest_addr.sin_addr);
printf("send data to UDP server %s:%d!\n", server_ip, port);
//设置该套接字为广播类型,这个很重要
int opt=1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt));
char send_buf[512] = "this is a broadcast data";
sendto(sockfd, send_buf, strlen(send_buf), 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));//发送数据
close(sockfd);
return 0;
}