虚拟机安装的麒麟系统V10 Lance桌面版本,测试udp组播通信,代码如下:
接收端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define MULTICAST_GROUP "239.255.0.1"
#define PORT 1234
#define LOCAL_IP "192.168.136.130" // 替换为你的本地IP
int main() {
int sockfd;
struct sockaddr_in addr;
char buffer[1024];
struct ip_mreq mreq;
// 1. 创建UDP Socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket");
exit(1);
}
// 2. 设置 SO_REUSEADDR(允许多个进程绑定同一端口)
int reuse = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
perror("setsockopt(SO_REUSEADDR)");
close(sockfd);
exit(1);
}
// 3. 绑定到本地IP(而非 INADDR_ANY)
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(LOCAL_IP); // 关键修改:绑定本地IP
// addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(PORT);
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
close(sockfd);
exit(1);
}
// 设置组播接口
struct in_addr localInterface;
localInterface.s_addr = inet_addr(LOCAL_IP);
if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF,
(char *)&localInterface, sizeof(localInterface)) < 0) {
perror("setsockopt(IP_MULTICAST_IF) failed");
close(sockfd);
exit(EXIT_FAILURE);
}
// 4. 加入组播组,并指定接收网卡(必须与绑定的本地IP一致)
mreq.imr_multiaddr.s_addr = inet_addr(MULTICAST_GROUP);
mreq.imr_interface.s_addr = inet_addr(LOCAL_IP); // 关键修改:指定接收网卡
// mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
perror("setsockopt(IP_ADD_MEMBERSHIP)");
close(sockfd);
exit(1);
}
printf("Waiting for multicast data on %s:%d...\n", MULTICAST_GROUP, PORT);
// 5. 接收数据
while (1) {
ssize_t recv_len = recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, NULL);
if (recv_len < 0) {
perror("recvfrom");
break;
}
buffer[recv_len] = '\0';
printf("Received: %s\n", buffer);
}
close(sockfd);
return 0;
}
发送端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
// #define MULTICAST_GROUP "224.1.1.1"
#define MULTICAST_GROUP "239.255.0.1"
#define PORT 1234
int main(int argc, char* argv[]) {
int sockfd;
struct sockaddr_in addr;
char* message = "Hello Multicast World!";
if (argc > 1) {
message = argv[1];
}
// 创建UDP套接字
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 设置TTL(生存时间)
unsigned char ttl = 32;
if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl))) {
perror("setsockopt IP_MULTICAST_TTL");
close(sockfd);
exit(EXIT_FAILURE);
}
// 2. 设置回环(启用)
int loop = 1;
if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) {
perror("setsockopt(IP_MULTICAST_LOOP)");
close(sockfd);
exit(1);
}
// 配置组播地址
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(MULTICAST_GROUP);
addr.sin_port = htons(PORT);
// 发送数据
if (sendto(sockfd, message, strlen(message), 0,
(struct sockaddr*)&addr, sizeof(addr)) < 0) {
perror("sendto failed");
}
else {
printf("Sent multicast message: %s\n", message);
}
close(sockfd);
return 0;
}
问题为:在接收端的代码中,socket绑定INADDR_ANY,组播通信测试没问题,绑定本地地址inet_addr(LOCAL_IP)时,组播不通,接收不到组播信息。