UDP的广播功能
广播通信指的是可以给处于局域网中的所有主机发送消息,只不过需要使用特定的广播地址,局域网大多数情况使用的是C类地址,对于某个C类网络而言,本地地址占8bit,如果本地地址8bit全部为1,则表示所有主机.

处于局域网的每台主机必须提供一个相同的端口号,这样才可以把接收的数据包保留,如果某个主机没有提供这个端口号,则收到的数据包会被丢弃。
由于广播功能属于Linux系统套接字文件的属性选项之一,所以想要启动广播功能,则需要设置套接字的属性选项,Linux系统中提供了两个函数接口来获取和设置套接字的属性选项,分别是getsockopt()和setsockopt(),使用规则如下所示:

1)函数参数
第一个参数:sockfd指的是创建的套接字对应的文件描述符,其实是socket()函数的返回值。
第二个参数:level指的是选项对应的协议级别,一般建议把该参数设置为SOL_SOCKET即可。
第三个参数:optname指的是选项的名称,比如广播选项的名称是SO_BROADCAST,如下:
注意:关于套接字选项的描述可以通过man手册的第7章来了解,输入 man 7 socket 即可。


第四个参数: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;
}
浙公网安备 33010602011771号