Subject: multicast
From: [email-masked] ("Bruce D. McLeod")

19 Mar 1997 15:36:12 -0800
Approved: [email-masked]
Distribution: cygnus
Message-ID: <[email-masked]>
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
X-Sender: [email-masked]
X-Mailer: Windows Eudora Pro Version 2.2 (32)
Original-To: [email-masked]
Original-Sender: [email-masked]

Has anyone successfully used multicast using the sys/sockets.h version
of the network stuff?  I am getting "This option is unsupported"
for the setsockopt:

      err = setsockopt( gListener, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                        (char *) &multiStruct, sizeof(multiStruct) );

Bruce

The full code...

#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>

#define PANIC() printf("panic\n"); exit(1);
#define ASSERT( x ) if ( (x) == 0 ) { PANIC(); }

const static int gMyPort = 5500;
const static char* gMyMultiIp = "225.1.1.88";
int gListener;

main( int argc, char **argv )
{
   if (argc > 1) {
      struct sockaddr_in localAddr;
      int err, value;
      struct ip_mreq multiStruct;
      char hostName[200];
      struct hostent* myHostent;

      // Set up listening socket.
      gListener = socket( AF_INET, SOCK_DGRAM, 0 );
      ASSERT( gListener != -1 );

      value = 1;
      err = setsockopt( gListener, SOL_SOCKET, SO_REUSEADDR,
                        (char *) &value, sizeof(value) );
      ASSERT( err != -1 );

      err = gethostname( hostName, 200 );
      ASSERT( err != -1 );
      myHostent = gethostbyname( hostName );
      ASSERT( myHostent != NULL );

      localAddr.sin_family = AF_INET;
      localAddr.sin_addr.s_addr = *((long *) myHostent->h_addr_list[0]);
      localAddr.sin_port = htons( gMyPort );

      err = bind( gListener, (struct sockaddr *) &localAddr,
sizeof(localAddr) );
      ASSERT( err != -1 );

      multiStruct.imr_multiaddr.s_addr = inet_addr( gMyMultiIp );
      multiStruct.imr_interface.s_addr = *((long *) myHostent->h_addr_list[0]);
      err = setsockopt( gListener, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                        (char *) &multiStruct, sizeof(multiStruct) );
      if (err == -1) perror("setsockopt failed");
      ASSERT( err != -1 );

      for (;;) {
         static const int bufsize = 200;
         char buf[bufsize];
         struct sockaddr fromAddr;
         int fromAddrLen, bytes;

         printf( "MultiTest: waiting for data\n" );

         fromAddrLen = sizeof(fromAddr);
         bytes = recvfrom( gListener, buf, bufsize, 0,
                           &fromAddr, &fromAddrLen );
         ASSERT( bytes >= 0 );

         if (bytes == 0) {
            printf( "MultiTest: disconnect received\n" );
            close( gListener );
            return 1;
         }

         printf( "MultiTest: msg received: %s\n", buf );
      }
   } else {
      static const char msg[] = "Hello world.";
      struct sockaddr_in remoteAddr;
      int bytes;

      int s = socket( AF_INET, SOCK_DGRAM, 0 );
      ASSERT( s != -1 );

      remoteAddr.sin_family = AF_INET;
      remoteAddr.sin_port = htons( gMyPort );
      remoteAddr.sin_addr.s_addr = inet_addr( gMyMultiIp );

      bytes = sendto( s, msg, strlen( msg ) + 1, 0,
                      (struct sockaddr *) &remoteAddr, sizeof(remoteAddr) );
      ASSERT( bytes == (int) strlen( msg ) + 1 );
      printf("MultiTest: msg sent\n");

      close( s );
   }

   return 0;
}

-
For help on using this list, send a message to
"[email-masked]" with one line of text: "help".