我試圖寫多點傳送服務器。我有兩個問題:與INADDR_ANY的套接字綁定和具有多接口的多播的特定接口
如何在多個接口(如ethernet/wifi接口)上發送多播通知。我是否需要爲每個接口創建多個套接字並綁定?
當使用INADDR_ANY地址綁定套接字時,描述符已準備好執行I/O操作(使用select調用),但是當我使用特定接口地址(例如ethernet/wifi)綁定時,描述符尚未準備好執行任何被卡住的操作只在選擇API。 那麼綁定一個套接字與默認地址(INADDR_ANY)或特定的接口地址有什麼區別?
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");
當INADD_ANY地址插座ID綁定選擇將收益和我能夠使用文件描述符進行讀取,但是當使用特定接口進行綁定時,則選擇永不返回,因爲沒有可供讀取的文件描述符。
當你綁定到'INADDR_ANY'然後調用'select'時,你會*檢查'select'返回什麼?並檢查'sockfd_set'中設置了哪些描述符?並談論錯誤,是任何系統調用失敗,你應該真的打印[錯誤](http://man7.org/linux/man-pages/man3/errno.3.html)(也許在[ strerror'](http://man7.org/linux/man-pages/man3/strerror.3.html))。 –
我已經將套接字描述符添加到sockfd_set,並且選擇將在與INADDR_ANY綁定後返回1,之後我使用FD_ISSET檢查套接字描述符並對特定描述符執行讀取操作。在其他情況下,select沒有返回,因爲我沒有提到超時。 – Narrator
當接收多播時,總是綁定到'INADDR_ANY'。在Linux中,如果綁定到特定的接口,您將無法接收多播。 – dbush