UDP的广播功能

广播通信指的是可以给处于局域网中的所有主机发送消息,只不过需要使用特定的广播地址,局域网大多数情况使用的是C类地址,对于某个C类网络而言,本地地址占8bit,如果本地地址8bit全部为1,则表示所有主机.
image
处于局域网的每台主机必须提供一个相同的端口号,这样才可以把接收的数据包保留,如果某个主机没有提供这个端口号,则收到的数据包会被丢弃。
由于广播功能属于Linux系统套接字文件的属性选项之一,所以想要启动广播功能,则需要设置套接字的属性选项,Linux系统中提供了两个函数接口来获取和设置套接字的属性选项,分别是getsockopt()和setsockopt(),使用规则如下所示:
image
1)函数参数
第一个参数:sockfd指的是创建的套接字对应的文件描述符,其实是socket()函数的返回值。
第二个参数:level指的是选项对应的协议级别,一般建议把该参数设置为SOL_SOCKET即可。
第三个参数:optname指的是选项的名称,比如广播选项的名称是SO_BROADCAST,如下:
注意:关于套接字选项的描述可以通过man手册的第7章来了解,输入 man 7 socket 即可。
image
image
第四个参数:optval指的是要设置的选项值,比如要启用广播选项,则设置optval为非0值。
第五个参数:optlen指的是选项值的长度,一般可以通过sizeof计算对应选项值的长度大小。

2)返回结果
setsockopt()函数和getsockopt()函数调用成功则返回0,如果调用失败,则返回-1和错误码。

点击查看代码
/****************************************************************************************
*
*	这是一个测试UDP套接字的广播属性的案例,本程序用于作为UDP服务器,服务器向网络号为
*	192.168.64的C类网络的广播地址192.168.64.255发送消息,测试结果应该为处于该网络的所有
*	主机都会收到相关的数据包。
*
* **************************************************************************************/
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

int main(int argc, char const *argv[])
{
	//1.创建UDP套接字             
	int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (udp_socket == -1)
	{
		fprintf(stderr, "udp socket error,errno:%d,%s\n",errno,strerror(errno));
		exit(1);
	}

	//2.获取UDP套接字的广播属性
	int flag = -1;
	socklen_t len = 4;
	getsockopt(udp_socket,SOL_SOCKET,SO_BROADCAST,(void *)&flag,&len);

	printf("flag = %d\n",flag); // 0

	//3.设置UDP套接字的广播属性
	int optval = 1;
	setsockopt(udp_socket,SOL_SOCKET,SO_BROADCAST,&optval,sizeof(optval));

	//4.获取UDP套接字的广播属性
	flag = -1;
	getsockopt(udp_socket,SOL_SOCKET,SO_BROADCAST,(void *)&flag,&len);
	printf("flag = %d\n",flag); // 非0
	
	//3.利用循环每隔5s想广播地址发送数据包
	char buf[128] = "I am teacher,this is test packet";
	
	struct sockaddr_in  dest_addr;
	dest_addr.sin_family 		= AF_INET; 						//协议族,是固定的
	dest_addr.sin_port   		= htons(atoi(argv[1]));			//服务器端口,必须转换为网络字节序
	dest_addr.sin_addr.s_addr   = inet_addr(argv[2]);			//服务器地址 "192.168.64.xxx"  

	while(1)
	{
		sendto(udp_socket,buf,strlen(buf),0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
		sleep(5);
	}
	

	return 0;
}
posted @ 2025-08-18 16:09  Lè_Sage  阅读(58)  评论(0)    收藏  举报