Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Why can't I join a multicast group

Posted on 2004-10-05
15
Medium Priority
?
943 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

610 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