YSM233 2025-06-01 09:21 采纳率: 0%
浏览 40

麒麟系统组播通信问题

虚拟机安装的麒麟系统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)时,组播不通,接收不到组播信息。

  • 写回答

4条回答 默认 最新

  • 阿里嘎多学长 2025-06-01 09:21
    关注

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    麒麟系统组播通信问题

    你遇到了麒麟系统V10 Lance桌面版本的组播通信问题,使用C语言编写了接收端代码,但是还没有解决问题。

    问题分析:组播通信需要在发送端和接收端都配置IP地址和端口号,确保发送端和接收端在同一个子网中。

    解决方案:

    1. 在发送端和接收端都配置IP地址和端口号,例如:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    #define PORT 1234
    #define GROUP_IP "239.1.1.1"
    
    int main() {
        int sock = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock < 0) {
            perror("socket");
            return -1;
        }
    
        struct sockaddr_in send_addr, recv_addr;
        send_addr.sin_family = AF_INET;
        send_addr.sin_port = htons(PORT);
        inet_pton(AF_INET, GROUP_IP, &send_addr.sin_addr);
    
        sendto(sock, "Hello, world!", 13, 0, (struct sockaddr *)&send_addr, sizeof(send_addr));
    
        close(sock);
        return 0;
    }
    
    1. 在接收端使用同样的IP地址和端口号,使用recvfrom函数接收数据:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    #define PORT 1234
    #define GROUP_IP "239.1.1.1"
    
    int main() {
        int sock = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock < 0) {
            perror("socket");
            return -1;
        }
    
        struct sockaddr_in recv_addr;
        recv_addr.sin_family = AF_INET;
        recv_addr.sin_port = htons(PORT);
        inet_pton(AF_INET, GROUP_IP, &recv_addr.sin_addr);
    
        char buf[1024];
        socklen_t addr_len = sizeof(recv_addr);
        int bytes_received = recvfrom(sock, buf, 1024, 0, (struct sockaddr *)&recv_addr, &addr_len);
        if (bytes_received < 0) {
            perror("recvfrom");
            return -1;
        }
    
        printf("Received: %s\n", buf);
    
        close(sock);
        return 0;
    }
    
    1. 在发送端和接收端都使用同样的IP地址和端口号,确保发送端和接收端在同一个子网中。

    如果你已经配置了IP地址和端口号,但是仍然遇到问题,可以检查网络配置、防火墙设置和路由表是否正确。

    评论

报告相同问题?

问题事件

  • 创建了问题 6月1日