簡體   English   中英

如果啟用了環回,為什么發件人沒有收到其組播UDP數據包?

[英]Why doesn't sender receive its multicast UDP packet if loopback is enabled?

在過去兩天中遇到以下問題:如果發件人已訂閱多播組,則回送的數據包是否會通過訪問點返回到發件人? 即使不是這種情況,是否有可能通過AP強制環回?

另外,為什么回送不能與以下代碼一起使用?

char * server_addr_name = "239.255.0.1"; // multicast group
int port_number = 8888;
int enable_loopback = 1;
int udp_socket;
struct message msg; // random message
char buffer[BUFFER_SIZE];

/* create socket */
struct sockaddr_in server_addr, rcv_addr;
socklen_t server_addr_size = sizeof(struct sockaddr_in);
socklen_t rcv_addr_size = sizeof(struct sockaddr_in);

/* initialize socket */
memset(& server_addr, 0, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(server_addr_name);
server_addr.sin_port = htons(port_number);
if ((udp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
    fprintf(stderr, "Error initializing UDP socket.\n");
    exit(EXIT_FAILURE);
}

struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(server_addr_name);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(udp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, & mreq, sizeof(mreq)) < 0) {
    fprintf(stderr, "Error on setting multicast membership on socket.\n");
    exit(EXIT_FAILURE);
}
unsigned char do_enable = (unsigned char) enable_loopback;
if (setsockopt(udp_socket, IPPROTO_IP, IP_MULTICAST_LOOP,
               & do_enable, sizeof(do_enable)) < 0) {
    fprintf(stderr, "Error on setting multicast loopback on socket.\n");
    exit(EXIT_FAILURE);
}

int read_size = 0;
while (1) {

    /* send the packet */
    if (sendto(udp_socket, &msg, sizeof(struct message), 0,
            (struct sockaddr *) & server_addr, server_addr_size) == -1) {
        fprintf(stderr, "Error on sending UDP packet.\n");
    }
    else
        printf("Sent my message.\n");

    /* get response from the server/multicast address */
    read_size = recvfrom(udp_socket, buffer, BUFFER_SIZE, 0,
                            (struct sockaddr *) & rcv_addr, & rcv_addr_size);
    if (read_size < 1)
        break;
    else
        printf("Got my packet!\n");
}

任何幫助表示贊賞。

setsockopt()的參數應為int,而不是無符號字符。

只是遇到了同樣的問題。 即使包與address:port匹配,Linux也不會​​在同一套接字上鏡像該包。 您應該創建另一個套接字udp_socket_receiver,方法與udp_socket和recvfrom一樣。 看起來IP_MULTICAST_LOOP意味着在發送方套接字之外的所有偵聽器上本地環回多播數據包。

如果發件人已訂閱多播組,則環回的數據包是否會通過訪問點返回到發件人?

我真的不知道是肯定的,但乍看之下答案是脂肪 如果網關將數據包反彈回它來自的位置,那么您將在復制流量,從而使多播點失效。

但是,發件人仍將收到該消息,因為在本地網絡中訂閱該組的任何人都將收到該消息,並且發件人已被訂閱。

即使不是這種情況,是否有可能通過AP強制環回?

我不知道,但是您可能不需要。 見下文。

為什么環回不能與以下代碼一起使用?

因為您忘記bind套接字。 您沒有告訴套接字應該在哪里偵聽,因此即使多播可能正常反彈,UDP也會丟棄數據包,因為它是連接到隨機端口的,而該端口可能不是8888。

socket()setsockopt(IP_ADD_MEMBERSHIP)之間添加以下塊。 為我工作:

struct sockaddr_in src;
memset(&src, 0, sizeof(src));
src.sin_family = AF_INET;
src.sin_port = htons(port_number);
src.sin_addr.s_addr = INADDR_ANY;
if (bind(udp_socket, (struct sockaddr*)&src, sizeof(src))) {
    perror("bind() failed");
    close(udp_socket);
    return EXIT_FAILURE;
}

使用完套接字后,您可能還應該close()套接字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM