当前位置: 首页 > 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.lryc.cn/news/594325.html

相关文章:

  • 前端环境搭建---基于SpringBoot+MySQL+Vue+ElementUI+Mybatis前后端分离面向小白管理系统搭建
  • Linux场景常见的几种安装方式
  • VSCode使用Jupyter完整指南配置机器学习环境
  • 在服务器无网络的环境下安装 VS Code Remote-SSH 组件
  • (5)从零开发 Chrome 插件:Vue3 Chrome 插件待办事项应用
  • 数控调压BUCK电路 —— 基于TPS56637(TI)
  • Spring Cloud Gateway高危隐患
  • jmeter如何做自动化接口测试?
  • jQuery多库共存
  • http基础一
  • 游戏剧情抄袭侵权比对报告:防止“爆款”变“爆雷”
  • C 语言经典编程题实战:从基础算法到趣味问题全解析
  • Qemu-NUC980(一):SOC框架代码添加
  • LeetCode 3202.找出有效子序列的最大长度 II:取模性质(动态规划)
  • 智能制造——48页毕马威:汽车营销与研发数字化研究【附全文阅读】
  • 【图像处理基石】什么是畸变校正?
  • 2025牛客暑期多校训练营2(部分补题)
  • 【LeetCode 热题 100】124. 二叉树中的最大路径和——DFS
  • 网络安全隔离技术解析:从网闸到光闸的进化之路
  • 【机器学习深度学习】魔塔社区模型后缀全解析:Base、Chat、Instruct、Bit、Distill背后的技术密码
  • leetcode丑数II计算第n个丑数
  • Java行为型模式---解释器模式
  • 大语言模型:人像摄影的“达芬奇转世”?——从算法解析到光影重塑的智能摄影革命
  • 核电子数字多道分析(DMCA)系统中,脉冲展宽的核心目的
  • 力扣:动态规划java
  • 基于单片机的火灾报警系统设计
  • 每日算法刷题Day50:7.20:leetcode 栈8道题,用时2h30min
  • 处理Electron Builder 创建新进程错误 spawn ENOMEM
  • C++ primer知识点总结
  • D. Traffic Lights 【Codeforces Round 1038, Div. 1 + Div. 2】