gpt4 book ai didi

c - 套接字与 INADDR_ANY 绑定(bind)以及具有多个接口(interface)的多播中的特定接口(interface)

转载 作者:行者123 更新时间:2023-11-30 17:02:25 24 4
gpt4 key购买 nike

我正在尝试编写多播服务器。我有两个问题:

  1. 如何在以太网/WiFi 接口(interface)等多个接口(interface)上发送多播公告。我需要为每个接口(interface)创建多个套接字并绑定(bind)吗?

  2. 当使用 INADDR_ANY 地址绑定(bind)套接字时,描述符已准备好执行 I/O 操作(使用 select 调用),但是当我与特定接口(interface)地址(例如以太网/wifi)绑定(bind)时,描述符尚未准备好执行任何操作仅卡在选择 api 处。那么绑定(bind)默认地址(INADDR_ANY)或特定接口(interface)地址的套接字有什么区别呢?

    int sd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sd < 0) {
    printf("scoket() failed");
    return sd;
    }

    int r = -1;

    int on = 1;
    if ((r = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on))) < 0) {
    printf("recv setsockopt(SO_REUSEADDR) failed");
    return r;
    }
    // add membership to receiving socket
    struct ip_mreq mreq;
    memset(&mreq, 0, sizeof(struct ip_mreq));
    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
    mreq.imr_multiaddr.s_addr = inet_addr(MDNS_ADDR);
    if ((r = setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(mreq))) < 0) {
    printf("recv setsockopt(IP_ADD_MEM) failed");
    return r;
    }
    // enable loopback in case someone else needs the data
    if ((r = setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &on, sizeof(on))) < 0) {
    printf("recv setsockopt(IP_MULTICAST_LOOP) failed");
    return r;
    }


    #ifdef IP_PKTINFO
    if ((r = setsockopt(sd, SOL_IP, IP_PKTINFO, (char *) &on, sizeof(on))) < 0) {
    printf("recv setsockopt(IP_PKTINFO) failed");
    return r;
    }
    #endif
    /* bind to an address */
    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(MDNS_PORT);
    //serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); /* receive multicast */
    serveraddr.sin_addr.s_addr = inet_addr("192.168.10.23"); /* receive multicast */
    if ((r = bind(sd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) < 0) {
    printf("recv bind()");
    }

在线程中等待描述符准备好 I/O(基本上都是读文件描述符)

            FD_ZERO(&sockfd_set);
FD_SET(svr->sockfd, &sockfd_set);
FD_SET(svr->notify_pipe[0], &sockfd_set);
printf("before select\n");
select(max_fd + 1, &sockfd_set, NULL, NULL, NULL);
printf("after select\n");

当套接字 ID 与 INADD_ANY 地址绑定(bind)时,选择将返回,并且我能够使用文件描述符进行读取,但当与特定接口(interface)绑定(bind)时,选择永远不会返回,因为没有可供读取的文件描述符。

最佳答案

  1. How to send multicast announcements on multiple interfaces like ethernet/ wifi interface. Do I need to create multiple sockets for each interface and bind?

没有。循环网络接口(interface)并依次为每个接口(interface)调用 setsockopt() 并使用适当的连接参数。您只需要一个套接字。

  1. When bind socket with INADDR_ANY address, descriptor is ready to do I/O operation (using select call)

这是不正确的。您的代码仅检查可读性。

but when I bind with specific interface address e.g ethernet/wifi then descriptor is not ready to perform any operation

这又是不正确的。您只检查可读性,而不检查“任何操作”。所有这意味着没有多播通过您绑定(bind)的地址传入。

it is stuck at select api only. So what is the difference between binding a socket with default address (INADDR_ANY) or specific interface address?

它确定您发送和接收的 IP 地址。

关于c - 套接字与 INADDR_ANY 绑定(bind)以及具有多个接口(interface)的多播中的特定接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36543977/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com