文章目錄
- 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 加入組播 |