【TCP/IP】广播 - 定义、原理及编程实现

        本文共计2974字,预计阅读时间4分钟

目录

广播

广播的原理及形式

广播的编程与实现

套接字选项设置

发送者

接收者

拓展资料


广播

        广播(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.150 \wedge 255.255.255.0 = 192.168.23.0

        那么其它的在广播域192.168.23.0内的所有主机就可以收到该设备发送的广播包。

拓展:

        如何计算广播地址?

        广播地址的计算方法为子网掩码“取反”后再与广播域进行“或运算”。
        例如:主机当前所属广播域为192(1100 0000).168(1010 1000).0.0,子网掩码为255.255.0.0,那么广播地址为(\vee是或操作,即 | ;\sim是取反操作):

192.168.0.0 \vee (\sim255.255.0.0) = 192.168.255.255

广播的编程与实现

套接字选项设置

        广播的编程实现与多播类似,区别在于对套接字选项的设置。通过 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博客

猜你喜欢

转载自blog.csdn.net/weixin_42839065/article/details/131375292
今日推荐