当前位置: 首页 > news >正文

UDP中的单播,多播,广播(代码实现)

文章目录

  • 1. UDP 单播(Unicast)示例
  • 2. UDP 广播(Broadcast)示例
  • 3. UDP 多播(Multicast)示例
      • 3.1 多播发送方示例
      • 3.2 多播接收方示例
  • 总结



1. UDP 单播(Unicast)示例

发送方向指定单个目标 IP 地址和端口发送数据,接收方绑定端口接收。

// UDP单播发送示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>int main() {int sockfd;struct sockaddr_in dest_addr;char *msg = "Hello UDP Unicast!";sockfd = socket(AF_INET, SOCK_DGRAM, 0);  // 创建UDP套接字if (sockfd < 0) {perror("socket error");return -1;}memset(&dest_addr, 0, sizeof(dest_addr));dest_addr.sin_family = AF_INET;dest_addr.sin_port = htons(12345);  // 目标端口inet_pton(AF_INET, "192.168.1.100", &dest_addr.sin_addr);  // 目标IPsendto(sockfd, msg, strlen(msg), 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr)); // 发送数据printf("UDP Unicast message sent.\n");close(sockfd);return 0;
}

2. UDP 广播(Broadcast)示例

向同一网段内所有主机发送数据,需要开启套接字广播权限。

// UDP广播发送示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>int main() {int sockfd;struct sockaddr_in broadcast_addr;char *msg = "Hello UDP Broadcast!";int broadcastEnable = 1;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("socket error");return -1;}// 允许广播权限if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable)) < 0) {perror("setsockopt error");close(sockfd);return -1;}memset(&broadcast_addr, 0, sizeof(broadcast_addr));broadcast_addr.sin_family = AF_INET;broadcast_addr.sin_port = htons(12345);inet_pton(AF_INET, "192.168.1.255", &broadcast_addr.sin_addr); // 广播地址,一般是子网广播地址sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr*)&broadcast_addr, sizeof(broadcast_addr));printf("UDP Broadcast message sent.\n");close(sockfd);return 0;
}

3. UDP 多播(Multicast)示例

多播发送时,发送方把数据发到多播地址和端口;接收方需要加入多播组才能收到消息。

3.1 多播发送方示例

// UDP多播发送示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>int main() {int sockfd;struct sockaddr_in multicast_addr;char *msg = "Hello UDP Multicast!";sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("socket error");return -1;}memset(&multicast_addr, 0, sizeof(multicast_addr));multicast_addr.sin_family = AF_INET;multicast_addr.sin_port = htons(12345);inet_pton(AF_INET, "239.255.0.1", &multicast_addr.sin_addr);  // 多播地址,必须是224.0.0.0~239.255.255.255范围sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr*)&multicast_addr, sizeof(multicast_addr));printf("UDP Multicast message sent.\n");close(sockfd);return 0;
}

3.2 多播接收方示例

接收方需要加入多播组,才能接收到该组播发送的消息。

// UDP多播接收示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>int main() {int sockfd;struct sockaddr_in local_addr;struct ip_mreq mreq;char buf[256];int nbytes;socklen_t addrlen;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd < 0) {perror("socket error");return -1;}// 绑定本地端口,监听多播数据memset(&local_addr, 0, sizeof(local_addr));local_addr.sin_family = AF_INET;local_addr.sin_port = htons(12345);local_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 监听所有本地接口if(bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)) < 0) {perror("bind error");close(sockfd);return -1;}// 加入多播组mreq.imr_multiaddr.s_addr = inet_addr("239.255.0.1"); // 多播组地址mreq.imr_interface.s_addr = htonl(INADDR_ANY);        // 本地接口if(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {perror("setsockopt mreq error");close(sockfd);return -1;}printf("Waiting for multicast message...\n");addrlen = sizeof(local_addr);while(1) {nbytes = recvfrom(sockfd, buf, sizeof(buf) - 1, 0, (struct sockaddr*)&local_addr, &addrlen);if(nbytes < 0) {perror("recvfrom error");break;}buf[nbytes] = '\0';printf("Received multicast message: %s\n", buf);}// 离开多播组(可选)setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));close(sockfd);return 0;
}

总结

通信方式发送代码重点需要设置接收代码重点
单播直接 sendto 指定目标 IP/端口无需特殊设置bind 监听端口,recvfrom接收
广播设置 SO_BROADCAST 选项需要开启广播权限bind监听端口,recvfrom接收
多播发送到多播组地址(224~239)发送无需特殊设置bind监听端口 + IP_ADD_MEMBERSHIP加入组播
http://www.xdnf.cn/news/1158751.html

相关文章:

  • securecrt连接服务器报错 Key exchange failed 怎么办
  • 在服务器无网络的环境下安装 VS Code Remote-SSH 组件
  • Linux-基础知识总结
  • 【算法300题】:双指针
  • 搭建大模型
  • Dockerfile配置基于 Python 的 Web 应用镜像
  • 前端静态资源免费cdn服务推荐
  • 【分布式 ID】详解百度 uid-generator(源码篇)
  • 企业安全防护:堡垒机技术解析
  • WireShark抓包分析TCP数据传输过程与内容详解
  • Linux场景常见的几种安装方式
  • 在C++里如何避免栈内存溢出
  • C++ primer知识点总结
  • 深度学习图像分类数据集—八种贝类海鲜食物分类
  • 基于Chinese-LLaMA-Alpaca-3的多模态中医舌诊辅助诊断系统设计与实现
  • day24——Java高级技术深度解析:单元测试、反射、注解与动态代理
  • 零基础 “入坑” Java--- 十三、再谈类和接口
  • ABP VNext + Playwright E2E:前后端一体化自动化测试
  • 苍穹外卖|项目日记(完工总结)
  • 基于Transformer的智能对话系统:FastAPI后端与Streamlit前端实现
  • 【RK3576】【Android14】ADB工具说明与使用
  • 企业级安全威胁检测与响应(EDR/XDR)架构设计
  • xavier nx上编译fast-livo过程中出现的问题记录
  • C++现代编程之旅:从基础语法到高性能应用开发
  • 【GameMaker】GML v3 的现行提案
  • Numpy库,矩阵形状与维度操作
  • (5)从零开发 Chrome 插件:Vue3 Chrome 插件待办事项应用
  • Vue3.6 无虚拟DOM模式
  • An End-to-End Attention-Based Approach for Learning on Graphs NC 2025
  • 线程(一):基本概念