当前位置: 首页 > 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.dtcms.com/a/289212.html

相关文章:

  • #SVA语法滴水穿石# (014)关于链式蕴含的陷阱
  • python生成密钥
  • FreeSwitch编译部署
  • 去中心化协作智能生态系统
  • DataFrame数据的常用方法
  • LeetCode 刷题【8. 字符串转换整数 (atoi), 9. 回文数】
  • 国产HMC7044调试记录
  • 【Elasticsearch】合适的锅炒合适的菜:性能与成本平衡原理公式解析
  • 拓展面试题之-rabbitmq面试题
  • MySQL笔记3
  • 试用SAP BTP 02:试用SAP HANA Cloud
  • 【机器学习【9】】评估算法:数据集划分与算法泛化能力评估
  • 图的表示法以及实现
  • 【人工智能99问】长短期记忆网络(LSTM)的结构和原理是什么?(12/99)
  • ROS_INFO_STREAM, 模拟cout流输出机制的ROS输出接口
  • 《棒球知识科普》NBA、MLB选秀状元·棒球1号位
  • Everything介绍
  • 《杜甫传》读书笔记与经典摘要(一)
  • 事务的传播行为,分别在spring和mysql中讲解
  • PyTorch模型Ensemble实现
  • 14.多播与广播
  • Vue3.6 无虚拟DOM模式
  • 基于本机如何建立一个vue项目
  • Linux主机 ->多机器登录
  • Openlayers 面试题及答案180道(121-140)
  • Chapter 3 Design of Switching Power Regulators
  • 两个数据表的故事:第 1 部分
  • MacBook的ARM架构(M芯片)操作虚拟机的docker拉取镜像问题
  • 深入浅出理解动态规划
  • 【Lua】大G表