Многоадресная передача с другого устройства, подключенного к тому же коммутатору, не работает, несмотря на трафик, показанный в tcpdump - PullRequest
0 голосов
/ 10 декабря 2018

Я пытаюсь получить многоадресные данные от встроенного устройства, подключенного к тому же коммутатору, что и мой рабочий стол, и не могу получать многоадресные сообщения в моем приложении recv ниже.Когда я выполняю tcpdump или запускаю Wireshark для интерфейса, подключенного к коммутатору, я вижу, что пакеты отображаются, но по какой-то причине их нет в моем приложении.

Я использую INADDR_ANY в качестве адреса интерфейса.Может ли кто-то пролить свет на то, почему сообщения будут находиться на Wireshark / Tcpdump, но не будут получены приложением?

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>

#define UDP_PORT 5403
#define UDP_GROUP "225.0.0.1"
#define MAX_BUFFER_SIZE 256

int main(int argc, char *argv[])
{
     struct sockaddr_in addr;
     int fd, nbytes;
     socklen_t addrlen;
     struct ip_mreq mreq;
     char msgbuf[MAX_BUFFER_SIZE];
     u_int reuse_port = 1;

     // Create a socket
     fd = socket(AF_INET,SOCK_DGRAM,0);
     if (fd < 0)
     {
        perror("create socket failed");
        return -1;
     }

     // allow multiple sockets to use the same PORT number
     if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_port, sizeof(reuse_port)) < 0)
     {
        perror("Reusing port number failed");
        return -1;
     }

     // set up destination address
     memset(&addr, 0, sizeof(addr));
     addr.sin_family = AF_INET;
     addr.sin_addr.s_addr = htonl(INADDR_ANY);
     addr.sin_port = htons(UDP_PORT);
     if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
     {
        perror("bind");
        return -1;
     }

     // Set the recvfrom timeout after 1 s
     struct timeval tv;
     tv.tv_sec = 2;
     tv.tv_usec = 0;
     if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
     {
         perror("Error setting recvfrom timeout\n");
         return -1;
     }

     // use setsockopt() to request that the kernel join a multicast group
     mreq.imr_multiaddr.s_addr = inet_addr(UDP_GROUP);
     mreq.imr_interface.s_addr = htonl(INADDR_ANY);
     if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
     {
        perror("setsockopt");
        return -1;
     }

     addrlen = sizeof(addr);
     printf("Begin recvfrom(...) infinite loop\n");
     while (true)
     {
         nbytes = recvfrom(fd, msgbuf, MAX_BUFFER_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
         if (nbytes < 0)
         {
            printf("recvfrom timeout\n");
         }
         else
         {
            printf("message received: %s\n", msgbuf);
         }
     }
     return 1;
}
...