?
Solved

Why can't I join a multicast group

Posted on 2004-10-05
15
Medium Priority
?
941 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

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
 
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

[Webinar] How Hackers Steal Your Credentials

Do You Know How Hackers Steal Your Credentials? Join us and Skyport Systems to learn how hackers steal your credentials and why Active Directory must be secure to stop them.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

764 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