JSON配置文件在嵌入式端的解析实战案例
2026/1/14 2:04:45
UDP 广播是指一台主机向所在子网(同一局域网)内的所有主机发送数据的通信方式,是 UDP 无连接特性的典型应用场景。
| 类型 | 格式 / 示例 | 特点 |
|---|---|---|
| 受限广播地址 | 255.255.255.255 | ① 不会被路由器转发;② 仅同一子网所有主机可接收 |
| 直接广播地址(定向广播) | 如 192.168.10.0/24 的广播地址为 192.168.10.255 | ① 主机段全为 1;② 可被路由转发(默认被路由器阻止,可配置放开);③ 可跨子网广播 |
若通过复制虚拟机搭建多主机测试环境,需解决网卡冲突问题:
sudo vim /etc/netplan/01-network-manager-all.yamlsudo netplan apply核心要点:
setsockopt设置SO_BROADCAST属性允许广播;#include <stdio.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <string.h> #include <stdlib.h> int main(void) { // 1. 创建UDP套接字 int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { perror("socket failed."); exit(1); } // 2. 设置套接字属性,允许发送广播 int opt = 1; setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, // 广播发送属性 &opt, // 非0:允许广播;0:禁止广播 sizeof(opt)); // 3. 配置广播目标地址和端口 struct sockaddr_in senderAddr; senderAddr.sin_family = AF_INET; // IPv4协议 senderAddr.sin_port = htons(9999); // 广播端口(需和接收方一致) senderAddr.sin_addr.s_addr = inet_addr("255.255.255.255"); // 受限广播地址 // 4. 发送广播消息 printf("send broadcast...\n"); char buff[BUFSIZ] = "大家好!新年快乐!"; int ret = sendto(sockfd, buff, strlen(buff) + 1, 0, (struct sockaddr*)&senderAddr, sizeof(senderAddr)); if (ret < 0) { perror("sendto failed."); } else { printf("had send broadcast %d bytes: %s\n", ret, buff); } // 5. 关闭套接字 close(sockfd); return 0; }核心要点:
INADDR_ANY接收所有网卡数据);recvfrom阻塞接收广播数据,并获取发送方 IP。#include <stdio.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <string.h> #include <stdlib.h> int main(void) { // 1. 创建UDP套接字 int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { perror("socket failed."); exit(1); } // 2. 配置接收方地址(绑定所有网卡+指定端口) struct sockaddr_in receiverAddr; receiverAddr.sin_family = AF_INET; // IPv4协议 receiverAddr.sin_port = htons(9999); // 和发送方一致的端口 receiverAddr.sin_addr.s_addr = INADDR_ANY; // 接收本机所有网卡的UDP数据 // 3. 绑定端口(广播接收方必须绑定) int ret = bind(sockfd, (struct sockaddr*)&receiverAddr, sizeof(receiverAddr)); if (ret == -1) { perror("bind failed."); exit(1); } // 4. 阻塞接收广播数据 char buff[BUFSIZ]; socklen_t len = sizeof(receiverAddr); ret = recvfrom(sockfd, buff, sizeof(buff), 0, (struct sockaddr*)&receiverAddr, &len); if (ret < 0) { perror("recvfrom failed."); exit(1); } // 5. 解析并打印发送方IP和接收的数据 char ipaddr[64]; const char* result = inet_ntop(AF_INET, &receiverAddr.sin_addr, ipaddr, sizeof(ipaddr)); if (result == nullptr) { printf("IP 地址转换失败\n"); } printf("received %d bytes from %s: %s\n", ret, ipaddr, buff); // 6. 关闭套接字 close(sockfd); return 0; }# 编译发送方 g++ Sender.cpp -o sender # 编译接收方 g++ Receiver.cpp -o receiver./receiver./senderreceived 21 bytes from 192.168.1.168: 大家好!新年快乐!SO_BROADCAST属性、用广播地址,无需 bind;接收方必须 bind,地址用INADDR_ANY。