Datagram socket broadcast Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Maddis
Knows some wx things
Knows some wx things
Posts: 36
Joined: Tue Jul 25, 2006 7:14 am

Datagram socket broadcast

Post by Maddis » Tue Aug 01, 2006 2:11 pm

Moved this from old already solved topic.
---
I'm having troubles to get that broadcast thingie working. Actually I'm having troubles to get it even compiled!

So far I've this:

Code: Select all

        m_serverAddr.Hostname(GROUP_DEFAULT)
        m_serverAddr.Service(INFO_PORT);
        m_sock = new wxDatagramSocket( m_serverAddr, wxSOCKET_NOWAIT );


       // Then later

        // This doesn't work without the struct-word.
        struct ip_mreq mreg;

        m_sock->SetEventHandler(*this, idUDPSocket);
        m_sock->SetNotify(wxSOCKET_INPUT_FLAG);
        m_sock->Notify(true);

        memset(&mreq,0,sizeof(ip_mreq));
        mreq.imr_multiaddr.s_addr = inet_addr(GROUP_DEFAULT);
        mreq.imr_interface.s_addr = htons(INADDR_ANY);
        m_sock->SetOption(IPPROTO_IP, IP_ADD_MEMBERSHIP, (char far *)&mreq,sizeof(mreq));




Errors are :
- `GROUP_DEFAULT' undeclared
- aggregate `ip_mreq mreg' has incomplete type and cannot be defined
- `IP_ADD_MEMBERSHIP' undeclared

Those are the worst ones. For example, I couldn't find GROUP_DEFAULT from wxwidgets includes or from mingw. All I want is to send broadcast messages!

One another thing. If/when I get that to work and I want to send message to specific IP can I just use SendTo and later if I want to send another broadcast, do I initialize socket again or can I just use Write to send broadcast?

benedicte
wxWorld Domination!
wxWorld Domination!
Posts: 1409
Joined: Wed Jan 19, 2005 3:44 pm
Location: Paris, France

Post by benedicte » Tue Aug 01, 2006 2:17 pm

I guess GROUP_DEFAULT and IP_ADD_MEMBERSHIP are constants and ip_mreq is a strucuture.

All these were defined in the original poster's code which was not included in the message you copied.

Either you can find the whole code, or you look for a complete sample (maybe in the <wxWidgets>/samples directory) to base your work on.

Maddis
Knows some wx things
Knows some wx things
Posts: 36
Joined: Tue Jul 25, 2006 7:14 am

Post by Maddis » Tue Aug 01, 2006 5:43 pm

Doh. I don't think there is whole code anywhere since that was all I could find.

Do you know the way to send broadcast messaged via Datagram-socket? It doesn't have to be the way I was trying to do earlier, but it was only way I could find how to do it.

benedicte
wxWorld Domination!
wxWorld Domination!
Posts: 1409
Joined: Wed Jan 19, 2005 3:44 pm
Location: Paris, France

Post by benedicte » Tue Aug 01, 2006 5:50 pm

I'm sorry, I didn't do anything like this.

upCASE
Site Admin
Site Admin
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

Re: Datagram socket broadcast

Post by upCASE » Wed Aug 02, 2006 7:13 am

Hi!
Maddis wrote:Errors are :
- `GROUP_DEFAULT' undeclared
- aggregate `ip_mreq mreg' has incomplete type and cannot be defined
- `IP_ADD_MEMBERSHIP' undeclared

Those are the worst ones. For example, I couldn't find GROUP_DEFAULT from wxwidgets includes or from mingw. All I want is to send broadcast messages!
Ok, I guess all subsequent post of this code relate to some code I posted a while back here http://forums.wxwidgets.org/viewtopic.php?t=4820

For completeness, I'll simply copy it:

Code: Select all

  wxIPV4address addr;
        addr.AnyAddress();
        addr.Service(30301);
        m_multicastSocket = new  wxDatagramSocket(addr,wxSOCKET_REUSEADDR);

        if(m_multicastSocket->Ok())
        {       ip_mreq mreg;
                memset(&mreq,0,sizeof(ip_mreq));
                mreq.imr_multiaddr.s_addr = inet_addr(GROUP_DEFAULT);   /* group addr you want to use*/
                mreq.imr_interface.s_addr = htons(INADDR_ANY);
                m_multicastSocket->SetOption(IPPROTO_IP, IP_ADD_MEMBERSHIP, (char far *)&mreq,sizeof(mreq));

                m_multicastSocket->SetNotify(wxSOCKET_INPUT_FLAG);
                m_multicastSocket->Notify(true);
                m_multicastSocket->SetEventHandler(*this, ID_MULTICAST);
        }
I don't know on what platform you're on, but using windows you'll have to include winsock.h for ip_mreq and IP_ADD_MEMBERSHIP. Using Unix I guess you need <sys/socket.h> and <netinet/in.h>.

GROUP_DEFAULT is a simple define to set the group all multicast "clients" will belong to. For example
#define GROUP_DEFAULT "224.0.1.5"

You "server" (there is no such thing when working with UDP) should use

Code: Select all

m_serverAddr.AnyAddress()
instead of

Code: Select all

m_serverAddr.Hostname(GROUP_DEFAULT)
The socket will not be on the group ip, but a local one.
Maddis wrote:One another thing. If/when I get that to work and I want to send message to specific IP can I just use SendTo and later if I want to send another broadcast, do I initialize socket again or can I just use Write to send broadcast?
You don't have to initialize the socket again. UDP sockets are connection-less, so it would be enough to set it up once and the use the correct wxIPv4address to send to.

To send to the group do something like

Code: Select all

wxIPv4address addr;
addr.Hostname(GROUP_DEFAULT)
addr.Service(INFO_PORT);
m_sock->SendTo(addr,data,dataLen;
To send to a specific IP, change Hostname and maybe Service accordingly.
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4

"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda

Maddis
Knows some wx things
Knows some wx things
Posts: 36
Joined: Tue Jul 25, 2006 7:14 am

Re: Datagram socket broadcast

Post by Maddis » Wed Aug 02, 2006 7:31 am

upCASE wrote: Ok, I guess all subsequent post of this code relate to some code I posted a while back here http://forums.wxwidgets.org/viewtopic.php?t=4820
Yes, thats the code I took.
I don't know on what platform you're on, but using windows you'll have to include winsock.h for ip_mreq and IP_ADD_MEMBERSHIP. Using Unix I guess you need <sys/socket.h> and <netinet/in.h>.
Client is on Windows and the other end is on something else. The problem is that even if I include winsock.h my compiler can't find ip_mreq nor IP_ADD_MEMBERSHIP. If I change ip_mreq to struct ip_mreq I get different kind of error suggesting that somekind of ip_mreq is defined somewhere but is not right one. Do I need define something to get those work? I already have _WIN32_IE=0x0600 on compiler's defines.
GROUP_DEFAULT is a simple define to set the group all multicast "clients" will belong to. For example
#define GROUP_DEFAULT "224.0.1.5"
I'm used to code on 'Unix-like' systems so these terms are not familiar to me. Is that GROUP_DEFAULT like a net mask or broadcast address(shouldn't it be in this case ending to .255?)? I mean that if I want to send _broadcast_ message that will work in _any_ network how is that done? Even if the ip-space if different it would work.
You "server" (there is no such thing when working with UDP) should use

Code: Select all

m_serverAddr.AnyAddress()
instead of

Code: Select all

m_serverAddr.Hostname(GROUP_DEFAULT)
The socket will not be on the group ip, but a local one.
My 'server' is non-windows machine and its all done already so only problem now is the Windows. :)

It seems that only(?) problem at the moment it that 'group' concept.

At the moment I have 'solved' the problem by sending the broadcast to local broadcast address for example '10.0.0.255'. It works here well, but won't work if the ip-space is for example 10.1.0.0.

boxcarmiba
Experienced Solver
Experienced Solver
Posts: 67
Joined: Wed Jun 14, 2006 7:35 am

Post by boxcarmiba » Wed Aug 02, 2006 8:34 am

If you want to do UDP broadcasting insert the following in your code at approporiate places:

Code: Select all

// if you know your broadcast address
m_serverAddr.Hostname("192.168.1.255"); // where your netmask is 
                                                               // 255.255.255.0 etc
// or you can send the data to the global broadcast address
m_serverAddr.Hostname("255.255.255.25");
m_serverAddr.Service( MY_SERVER_PORT ); // whatever port number your
                                                                  // using as your server
m_sock = new wxDatagramSocket( m_serverAddr, wxSOCKET_NOWAIT );
// set up your eventhandler, notify etc as you require... e.g.
m_sock->SetNotify( wxSOCKET_INPUT_FLAG );
m_sock->Notify( true );
// now add the little bit of broadcast magic
int broadcast = 1;
if( !m_sock->SetOption( SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof( broadcast ) ) )
    printf( "could not initialize broadcasting" );
that's really all there is to it. Do your SendTo and RecvFrom as you would do normally from the port. your SendTo's will be broadcasted to your local machines as per your specified broadcast address.

upCASE
Site Admin
Site Admin
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

Post by upCASE » Wed Aug 02, 2006 9:03 am

GROUP_DEFAULT would be the broadcast address.
I made an error here: I'm doing a multicast, not broadcast. Multicast addresses range fro 224.0.0.0 to 239.255.255.255.
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4

"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda

boxcarmiba
Experienced Solver
Experienced Solver
Posts: 67
Joined: Wed Jun 14, 2006 7:35 am

Post by boxcarmiba » Wed Aug 02, 2006 9:09 am

I think that's the basic problem in this thread. Some people are talking broadcast and others are talking multicast. :)

Maddis
Knows some wx things
Knows some wx things
Posts: 36
Joined: Tue Jul 25, 2006 7:14 am

Post by Maddis » Wed Aug 02, 2006 9:12 am

boxcarmiba wrote:If you want to do UDP broadcasting insert the following in your code at approporiate places:

Code: Select all

m_serverAddr.Hostname("255.255.255.25");
that's really all there is to it. Do your SendTo and RecvFrom as you would do normally from the port. your SendTo's will be broadcasted to your local machines as per your specified broadcast address.
That done it! Except that hostname should've been 255.255.255.255 and I had to open socket with m_serverAddr.AnyAddr(), but other than that the thing worked! Thanks!

upCASE
Site Admin
Site Admin
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

Post by upCASE » Wed Aug 02, 2006 9:49 am

boxcarmiba wrote:I think that's the basic problem in this thread. Some people are talking broadcast and others are talking multicast. :)
My fault: I should learn to read the entire post :)
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4

"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda

Troels
Experienced Solver
Experienced Solver
Posts: 79
Joined: Fri Jan 07, 2005 12:02 pm
Location: Denmark

Re: Datagram socket broadcast

Post by Troels » Fri Feb 23, 2007 3:11 pm

upCASE wrote:

Code: Select all

  wxIPV4address addr;
        addr.AnyAddress();
        addr.Service(30301);
        m_multicastSocket = new  wxDatagramSocket(addr,wxSOCKET_REUSEADDR);
...
For the record:
wxSOCKET_REUSEADDR when used with wxDatagramSocket doesn't do anything currently:
http://sourceforge.net/tracker/index.ph ... tid=309863

/Troels

Post Reply