我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=33nqakp1y9esg
一、理解广播地址:
专门用于同时向网络中所有工作站进行发送的一个地址叫做广播地址。在使用TCP/IP 协议的网络中,主机标识段host ID 为全1 的IP 地址为广播地址。如果你的IP为:192.168.1.39,子网掩码为:255.255.255.0,则广播地址为:192.168.1.255;如果IP为192.168.1.39,子网掩码为:255.255.255.192,则广播地址为:192.168.1.63(255-192)(来源:https://blog.csdn.net/wangquan1992/article/details/89890816)
1、本地受限广播
如果想在整个网络中广播数据,要向255.255.255.255发送数据包,这种数据包不会被路由,它只能到达本物理网络中的所有主机,此种广播叫有限广播;
简单理解,就是交换机内连接的设备,都能接收到该广播消息,无论该设备的IP如何配置;
2、直接广播,定向广播;
如果只想在本网络内广播数据(假设本网广播地址192.168.1.255),只要向192.168.1.255发送数据包即可,这种数据包可以被路由,它会经由路由器到达本网段内的所有主机,此种广播也叫直接广播,直接广播也可以向指定网段进行广播,前提是指定目标网段(x.x.x.255);
二、如何实现广播发送和接收;
UDP发送端,需要配置发送广播消息的选项:
代码语言:javascript复制#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int setsockopt(int sockfd, int level, int optname,
const void *optval, socklen_t optlen);
参数说明
level:
SOL_SOCKET
optname:
SO_BROADCAST 允许发送广播数据包
SO_RCVBUF 接收缓冲区大小
SO_SNDBUF 发送缓冲区大小
/设置该套接字为广播类型
int opt=1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt));
参考代码:
代码语言:javascript复制//通过广播地址:4001端口发送给所有监听4001端口的设备
int send_config_data_from_broadcast(shared_ptr<string> json_str){
struct sockaddr_in b_addr;
int socked=socket(AF_INET,SOCK_DGRAM,0);
if(socked<0)
{
perror("sock failed");
return 1;
}
int yes=1;
if(setsockopt(socked,SOL_SOCKET,SO_BROADCAST,&yes,sizeof(yes))<0)
{
perror("setsockopt failedn");
return 2;
}
b_addr.sin_family=AF_INET;
b_addr.sin_addr.s_addr=inet_addr("255.255.255.255");
b_addr.sin_port=htons(4001);
int b_addr_len=sizeof(b_addr);
printf("nrsend %s from broadcast.nr", json_str->c_str());
int send_len = sendto(socked, json_str->c_str(), json_str->length(), 0,(struct sockaddr *)&b_addr, b_addr_len);
if (send_len < 0) {
printf("nrsend error.nr");
exit(EXIT_FAILURE);
}
printf("send success %d.nr",send_len);
return 0;
}
UDP服务器端,需要接收广播消息,这里和普通UDP的服务器就可以接收到广播消息!
参考代码1:
代码语言:javascript复制#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netdb.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<arpa/inet.h>
int main(){
int sockListen;
if((sockListen = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
printf("socket failn");
return -1;
}
int set = 1;
setsockopt(sockListen, SOL_SOCKET, SO_REUSEADDR, &set, sizeof(int));
struct sockaddr_in recvAddr;
memset(&recvAddr, 0, sizeof(struct sockaddr_in));
recvAddr.sin_family = AF_INET;
recvAddr.sin_port = htons(4001);
recvAddr.sin_addr.s_addr = INADDR_ANY;
if(bind(sockListen, (struct sockaddr *)&recvAddr, sizeof(struct sockaddr)) == -1){
printf("bind failn");
return -1;
}
int recvbytes;
char recvbuf[1024] = "