Frage

habe ich einen Code, in dem Multicast-Datagramme senden. Ein kritisches Stück Code:

uint32_t port;
int sockfd, err_ip;
const uint32_t sizebuff = 65535 - (20 + 8);
unsigned char *buff = (unsigned char *) malloc(sizebuff);
struct sockaddr_in servaddr, cliaddr;
struct in_addr serv_in_addr;
struct ip_mreq req;

port = str2uint16(cmdsrv->ipport);
bzero(buff, (size_t)sizebuff);
bzero(&servaddr, sizeof(servaddr));
bzero(&serv_in_addr, sizeof(serv_in_addr));
err_ip = inet_aton(cmdsrv->ipaddr, &serv_in_addr);

if(( err_ip != 0 ) && ( port != 0 )) {
   servaddr.sin_family = AF_INET;
   servaddr.sin_addr = serv_in_addr;
   servaddr.sin_port = htons(port);
   memcpy(&req.imr_multiaddr,&serv_in_addr,sizeof(req.imr_multiaddr));
   req.imr_interface.s_addr = INADDR_ANY;
   sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

   if( sockfd == -1 ) {
      int outerror = errno;
      char *retstr = "Couldn't open socket\n";
      pthread_exit(retstr);
   }
   else {
      struct in_addr ifaddr;
      ifaddr.s_addr = INADDR_ANY;
      int optres3 =
         setsockopt( sockfd, IPPROTO_IP, IP_MULTICAST_IF, &ifaddr,
                     sizeof( ifaddr ));
      if( optres3 == -1 ) {
         int perrno = errno;
         char *retstr = "Can't set IP_MULTICAST_IF for socket\n";
         printf( "Error setsockopt: ERRNO = %s\n", strerror( perrno ));
         printf( "%s",retstr );
         pthread_exit(retstr);
      }

      unsigned char ttl = 32;
      int optres2 =
         setsockopt( sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
                     sizeof( ttl ));
      if( optres2 == -1 ) {
         int perrno = errno;
         char *retstr = "Can't set IP_MULTICAST_TTL for socket\n";
         printf("Error setsockopt: ERRNO = %s\n",strerror(perrno));
         printf("%s",retstr);
         pthread_exit(retstr);
      }

      int optres =
         setsockopt( sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req,
                     sizeof( req ));
      if( optres == -1 ) {
         int perrno = errno;
         char *retstr = "Can't join to multicast-group\n";
         printf("Error setsockopt: ERRNO = %s\n",strerror(perrno));
         printf("%s",retstr);
         pthread_exit(retstr);
      }

      // Bind port with socket
      uint16_t cliport;
      cliaddr.sin_family = AF_INET;
      cliaddr.sin_addr.s_addr = INADDR_ANY;

      if( strcmp( cmdsrv->ipport, "16011" ) == 0 ) {
         cliport = str2uint16("16003");
         cliaddr.sin_port = htons(cliport);
      }
      else if( strcmp( cmdsrv->ipport, "16012" ) == 0 ) {
         cliport = str2uint16("16004");
         cliaddr.sin_port = htons(cliport);                     
      }
      else {
         printf("Device hasn't such port");
         pthread_exit(NULL);
      }

      int bindres =
         bind( sockfd, (struct sockaddr*)&cliaddr, sizeof( cliaddr ));
      if( bindres == -1 ) {
         int perrno = errno;
         perror("Error in bind\n");
      }
      // ADD 1 BYTE
      data rawdata;
      rawdata.desc = 23;
      printf( "SIZEOF = %d\n", sizeof( *( cmdsrv->cmd )));
      memcpy( &rawdata.cmd, cmdsrv->cmd, sizeof( *( cmdsrv->cmd )));
      printf( "RAWDATA: desc = %d, cmd = %d\n", rawdata.desc, rawdata.cmd );

      int outerror = 0;
      printf( "Send command to IP:\n addr = %s, port = %d\n",
         inet_ntoa( servaddr.sin_addr ), ntohs( servaddr.sin_port ));
      int size = sendto( sockfd, &rawdata, sizeof( rawdata ), 0,
         (struct sockaddr*)&servaddr, sizeof( servaddr ));
      if( size == -1 ) {
         perror("Can't send command to socket");
      }
      ...

Manchmal erfolgreich Programm ausgeführt wird (in diesem Moment habe ich IP - 192.168.80.122). Ich kann meinen Multicast-Datagramm von wireshark erfassen. Das ist alles in Ordnung.

Aber wenn ich meine IP zu 192.168.1.2 ändern, ich Fehlermeldung erhalten, wenn sie aufgerufen wird,

int optres =
   setsockopt( sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req,
               sizeof( req ));

Und ich kann mein Multicast-Paket nicht einmal erfassen. Es wird nichts gesendet. Wo der Fehler?

War es hilfreich?

Lösung

Wenn es für eine IP funktioniert, aber nicht für einen anderen, vielleicht diese helfen können.

Was bedeutet? "IP_ADD_MEMBERSHIP: No such device" mean

Es bedeutet, dass das Werkzeug versucht, Multicast zu verwenden, aber die Netzwerk-Schnittstelle nicht unterstützt es Es gibt zwei mögliche Ursachen:

  • Ihre Maschine nicht Multicast-Unterstützung nicht aktiviert. Zum Beispiel auf Linux und FreeBSD ist es möglich, einen Kernel zu kompilieren, die nicht Multicast unterstützt.

  • Sie haben noch einen Weg für Multicast-Verkehr. Einige Systeme fügen Sie nicht diese standardmäßig aktiviert und Sie müssen laufen. route add -net 224.0.0.0 netmask 224.0.0.0 eth0 (oder ähnliches). Wenn Sie nur RAT verwenden, in Unicast-Modus mögen, ist es möglich, die Multicast-Route auf der Loopback-Schnittstelle hinzuzufügen.

Andere Tipps

IP_ADD_MEMBERSHIP und bind() sind nur erforderlich, zur Aufnahme von Multicast Verwendung IP_MULTICAST_IF stattdessen effektiv eine "send-only-Mitgliedschaft" eine Multicast-Gruppe.

IP_MULTICAST_IF setzt den Kernel Multicast-Pakete für eine bestimmte Gruppe auf eine bestimmte Schnittstelle zu senden, ist es wirkungsvoll „send-only“, wie Sie nicht in der Lage sein wird, den Verkehr auf dieser Gruppe nach Einstellung zu erhalten. Dies hängt von der Plattform. Posix Plattformen im Allgemeinen funktionieren auf diese Weise als Optimierungs, während Win32 wird Software-Ebene durchführt Routing lokal erzeugten Pakete zu propagieren

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top