Solved

Why can't I join a multicast group

Posted on 2004-10-05
15
932 Views
Last Modified: 2012-08-14
I am trying to join a multi cast group but I am getting WSAENOPROTOOPT, 10042  returned by WSAGetLastError.  When I look at the fields populated in the ip_mreq struct the curret ip values are there 10.10.10.1 for interface and 227.10.10.10 for multicast group.  Following is a snippet of code which I am trying to get to work, along with debugging stuff to check values in the debugger.  Any suggestions on where to start looking for the fix for this?


// request to join group    
    ip_mreq req;

    // get the currently selected local interface.
    req.imr_interface = m_hostIPs[m_IPIndex];

    MulticastGroups::const_iterator it = m_joinedGroups.begin();
    MulticastGroups::const_iterator ite = m_joinedGroups.end();
   
    while (it != ite) {
        long group = inet_addr(it->c_str());

        memcpy(&req.imr_multiaddr, &group, sizeof(group));
        char* str = inet_ntoa(req.imr_interface);
        str = inet_ntoa(req.imr_multiaddr);
        int x = setsockopt(m_recvSocket, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,
                   (char*)&req, sizeof(req));
        x= WSAGetLastError();
        it++;
    }
0
Comment
Question by:mvoiers
  • 6
  • 6
15 Comments
 

Author Comment

by:mvoiers
ID: 12230849
In case it matters I am running Windows 2k and visual studio 2003.  Also another way to look at this, I want to call setsockopt with an ip_mreq populated with two ip address, (local interface and group),  and the option IP_ADD_SOURCE_MEMBERSHIP.  I have already created a socket with the following socket(AF_INET, SOCK_DGRAM, 0).
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12248440
MSDN says that IPPROTO_IP and IP_ADD_SOURCE_MEMBERSHIP is only valid for WinXP and Server 2003.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/ipproto_ip_socket_options.asp

Regards, Alex
0
 

Author Comment

by:mvoiers
ID: 12249173
Yes, I caught the IP_ADD_SOURCE_MEMBERSHIP and replaced it with IP_ADD_MEMBERSHIP...still no luck.  Another question I have run into which I think I know the answer is that I just need one socket which I can join numerous groups on, I don't need to create a socket for each group?  

Here is how I am trying to read from the sockets, I think it is safe to say I can ditch this iteration over multiple sockets and just use one socket, but either way I don't seem to be having any luck....

    SocketsList::const_iterator it = m_recvSocket.begin();
    SocketsList::const_iterator ite = m_recvSocket.end();
    int byteCount = 0;
    for (; it != ite; it++)
    {
        for (int i = 0; i < m_maxReads; i++, byteCount++)
        {
            // read from the socket
            numBytes = recvfrom(*it, buffer, s_defaultMaxBuffer, 0,
                reinterpret_cast<sockaddr *>(&fromAddress), &fromLength);

            // check to make sure there wasn't an error
            if (numBytes < 0)
            {
//                return byteCount;
                break;
            }

            // pass buffer to handler code
     
        }
    }

0
 

Author Comment

by:mvoiers
ID: 12249814
after joining numerous groups I perform a bind, passing in the ip address of my desired local interface.    All the winsock calls return without error.  The one thing that is concerning me is that I only receive packets on my unicast address, which is the address I don't want to receive anything on if I am in multicast.  Anything sent to the multicast address is never received....no matter what I try.  I am now back to creating just one socket and doing joins on that socket instead of creating a socket for each join.  I believe this is the correct approach instead of creating a socket for each join.

Here is basically what I am doing now

// create a socket, there doesn't seem to be any other options here
m_recvSocket = socket(AF_INET, SOCK_DGRAM, 0);

    // go through all the groups we want to join and join then using setsockopt
    MulticastGroups::const_iterator it = m_joinedGroups.begin();
    MulticastGroups::const_iterator ite = m_joinedGroups.end();
   
    while (it != ite) {
        long group = inet_addr(it->c_str());

        memcpy(&mreq.imr_multiaddr, &group, sizeof(group));
        char* str = inet_ntoa(mreq.imr_interface);
        str = inet_ntoa(mreq.imr_multiaddr);
        int x = setsockopt(m_recvSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                           (char*)&mreq, sizeof(mreq));
        x = WSAGetLastError();
        it++;
    }


    char reuseaddr = 1;
    int r = setsockopt(m_recvSocket, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
        sizeof(reuseaddr));

    // bind the input socket to the DIS port
    struct sockaddr_in address;

    memset(&address, 0, sizeof(address)) ;
    address.sin_family      = AF_INET;
    address.sin_port        = htons(m_port);
    address.sin_addr        = hostAddr;

   

    int x = bind(m_recvSocket, reinterpret_cast<const sockaddr *>(&address),
        sizeof(address));
    x = WSAGetLastError();

    // setup the input socket for nonblocking I/O
    unsigned long flags = 1;
    if (ioctlsocket(m_recvSocket, FIONBIO, &flags) != 0)



// now to read something

numBytes = recvfrom(m_recvSocket, buffer, s_defaultMaxBuffer, 0,
            reinterpret_cast<sockaddr *>(&fromAddress), &fromLength);


this is the jist of all the code....can anyone see any glaring errors?  

0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12249985
Did you convert hostAddr by using htonl ?
Did you get any errors or simply nothing to receive?
Did you try a TCP/IP connection before?
Is there any firewall that could prevent you from receiving messages?

Regards, Alex


0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12250033
If you set the socket to non-blocking recvfrom most likely returns not reading anything. You have to check  WSAGetLastError() if it equals WAE_WOULDBLOCK. That is ok, and you have to poll after sleeping some milliseconds til you'll get anything.

Regards, Alex


   
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12250054
Correction: it's WSAEWOULDBLOCK.
0
 

Author Comment

by:mvoiers
ID: 12250387
memcpy(&hostAddr, &ladr, sizeof(unsigned long));

I look at the hostAddr struct in the debugger and it contains the correst IP.


I do get the WSAEWOULDBLOCK when I try to receive.

As for TCP/IP if I do a unicast transmission, I get everything fine.  Its just when I tell my packet generation program to go multicast I never see anything.  I can see the packets being generated using the Ethereal packet sniffer and the source and destination ip address looks good.





0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12250637
>>>> I look at the hostAddr struct in the debugger and it contains the correst IP

but hostAddr should be in net order that is big endian (means byte order is 3 2 1 0). You should try

    address.sin_addr = htonl(hostAddr);

However, if it worked with TCP/IP the address is ok.

>>>> I do get the WSAEWOULDBLOCK when I try to receive.

As i told you: WSAEWOULDBLOCK is the "normal" error return after setting a socket to non-blocking. You need an endless loop like that to receive data:

    while (true)
    {
          numBytes = recvfrom(m_recvSocket, buffer, s_defaultMaxBuffer, 0,
            reinterpret_cast<sockaddr *>(&fromAddress), &fromLength);
          if (numBytes == SOCKET_ERROR)
          {
               unsigned int err = WSAGetLastError());
               if (err == WSAEWOULDBLOCK)
               {
                       Sleep(10);   // give other threads some process time
                       continue;     // try again
               }
               // error
               return 1;
          }
          // received data      

    }

Regards, Alex
   

   
0
 

Author Comment

by:mvoiers
ID: 12250864
Yes, the function the recvfrom call is in is called endlessly....otherwise the unicast wouldn't work either.  Since when I broadcast in unicast everything works fine, that would seem to suggest the framework is ok, just missing some sort of winsock config or other issue?



0
 

Author Comment

by:mvoiers
ID: 12251577
Well...looks like I get the points myself....the "join group had to take place after the bind".....jeeesh....join group should return an error if socket already bound.


0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 12256955
Gratulations. Try to accept your own comment ;-)  or go CS

Regards, Alex
0
 

Accepted Solution

by:
modulo earned 0 total points
ID: 12723901
PAQed with points refunded (500)

modulo
Community Support Moderator
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now