目录
广播
广播的原理及形式
广播的编程与实现
套接字选项设置
发送者
接收者
拓展资料
广播
广播(Broadcast)是指封包在计算机网络中传输时,目的地址为网络中所有设备的一种传输方式。这里所说的“所有设备”也被限定在一个范围之中,这个范围被称为“广播域”。
基于广播的特性,广播普遍应用于局域网中,而不用于广域网。
广播的原理及形式
多播的数据传输协议与多播相同,通过UDP协议完成。同时,广播又分为两种形式,分别是:
- 直接广播 (能够跨越不同网络的广播)
- 本地广播 (只在本地网络中的广播)
直接广播用于向特定区域内(已知目标主机网络地址)主机传输数据。使用上,若已知目标主机IP地址及子网掩码为192.168.1.0/24,那么广播地址即为192.168.1.255。(需要注意的是,255.255.255.255为受限广播地址,不能被使用),按照该地址发送数据包时,路由器将会把数据包发送给192.168.1.1 ~ 192.168.1.254下所有主机,如下图所示:
本地广播用于本地网络内的通信(只能用于局域网下)。无论特定主机位于何种 IP 网络上,当前的主机始终可以使用 255.255.255.255 这个地址向本地网络上的每个节点发送数据包。比如,在192.168.0网段下的任意一台主机,向255.255.255.255发送数据包,那么在192.168.0网段下所有的主机将会收到该数据包,同时,该数据包也不会被转发到其他网段去。如下图所示:
拓展:
如何知道一台主机是属于哪一个广播域?
用主机的IP地址与子网掩码进行“与运算”即可知道该主机属于哪一个广播域。
例如:一台主机的IP地址为192(1100 0000).168(1010 1000).23(0001 0111).150(1001 0110),子网掩码为255(1111 1111).255.255.0,那么它所属的广播域就是(实际计算是以二进制的哦~):
那么其它的在广播域192.168.23.0内的所有主机就可以收到该设备发送的广播包。
拓展:
如何计算广播地址?
广播地址的计算方法为子网掩码“取反”后再与广播域进行“或运算”。
例如:主机当前所属广播域为192(1100 0000).168(1010 1000).0.0,子网掩码为255.255.0.0,那么广播地址为(是与操作,即&;是取反操作):
广播的编程与实现
套接字选项设置
广播的编程实现与多播类似,区别在于对套接字选项的设置。通过 setcokopt 函数,将选项级别设为 SOL_SOCKET ,对应选项为 SO_BROADCAST 。选项设置为1,表示“可以进行数据广播”。
int send_sock;
int so_brd = 1; //对变量进行初始化以将 SO_BROADCAST 选项信息设为 1
send_sock = socket(PF_INET , SOCK_DGRAM , 0);
setsockopt(send_sock , SOL_SOCKET , SO_BROADCAST , (void*) & so_brd , sizeof(so_brd));
发送者
在实现上与多播类似,主要集中在套接字选项的设置。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUF_SIZE 1024
//报错消息发送
void Sender_message(char *message)
{
puts(message);
exit(1);
}
int main(int argc, char *argv[])
{
int send_sock;
struct sockaddr_in brd_addr;
FILE *fp;
char buf[BUF_SIZE];
int so_brd=1;
send_sock=socket(PF_INET, SOCK_DGRAM, 0);
if(send_sock==-1)
{
Sender_message((char*)"socket creation error");
}
memset(&brd_addr, 0, sizeof(brd_addr));
brd_addr.sin_family=AF_INET;
brd_addr.sin_addr.s_addr=inet_addr(argv[1]);
brd_addr.sin_port=htons(atoi(argv[2]));
setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST, (void*)&so_brd, sizeof(so_brd));
fp=fopen(argv[3], "r");
if(fp==NULL)
{
Sender_message((char*)"file open error");
}
while(!feof(fp))
{
fgets(buf, BUF_SIZE, fp);
sendto(send_sock, buf, strlen(buf), 0, (struct sockaddr*)&brd_addr, sizeof(brd_addr));
}
close(send_sock);
return 0;
}
接收者
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUF_SIZE 1024
// 报错消息发送
void Sender_message(char *message)
{
puts(message);
exit(1);
}
int main(int argc, char *argv[])
{
int recv_sock;
struct sockaddr_in addr;
int str_len;
char buf[BUF_SIZE];
recv_sock = socket(PF_INET, SOCK_DGRAM, 0);
if (recv_sock == -1)
{
Sender_message((char *)"socket creation error");
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(atoi(argv[1]));
if (bind(recv_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1)
{
Sender_message((char *)"bind error");
}
while (1)
{
str_len = recvfrom(recv_sock, buf, BUF_SIZE - 1, 0, NULL, 0);
if (str_len < 0)
{
break;
}
buf[str_len] = 0;
fputs(buf, stdout);
}
close(recv_sock);
return 0;
}
运行结果:
拓展资料
[1] setsockopt函数功能及参数详解 - 博客园
[2] 本地广播与定向广播到底有什么区别? - 知乎
[3] 多播与广播原理分析及区别 - CSDN博客