文章目录
- 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 加入组播 |