Sending broadcast messages is useful for things like discovering how many of a particular resource are currently available, synchronising states, instant messaging, enumerating the devices on a network of "internet of things" devices, etc.
To build in Code::Blocks just create a new empty Frame-based wxWidgets 2.8.12 project and add the 4 files to the project. This example used the wxSmith GUI builder, only the File / Send menu command needs to be added, with ID idMenuSend, var name MenuItem3, and EVT_MENU handler BroadcastFrame::OnMenuItemSendSelected().
Test environment:
IDE: Code::Blocks nightly build svn 10136
wxWidgets version: 2.8.12 (the current recommended version of wxWidgets to use with Code::Blocks), Unicode build, static link
OS: MS Windows 7 (32-bit)
Compiler: TDM mingw ver 4.9.2
Using the File / Send menu command should result in a UDP broadcast message being sent and received on a log message box showing the message, i.e. "Test using port..." If you have another instance running on another computer on your local network it should also show the same message (if permitted by firewalls).
Main header:
Code: Select all
/***************************************************************
* Name: BroadcastMain.h
* Purpose: Defines Application Frame
* wxWidgets 2.8.12 sample to send and receive a UDP broadcast datagram
* Author: CJS ()
* Created: 2016-01-27
* Copyright: CJS ()
* License:
Excepting if sections are specifically annotated that other
conditions apply, the following MIT license shall apply:
Copyright (c) 2016 CJS
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
https://opensource.org/licenses/MIT
**************************************************************/
#ifndef BROADCASTMAIN_H
#define BROADCASTMAIN_H
//(*Headers(BroadcastFrame)
#include <wx/menu.h>
#include <wx/frame.h>
#include <wx/statusbr.h>
//*)
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
# pragma hdrstop
#endif
// for all others, include the necessary headers
#ifndef WX_PRECOMP
# include "wx/wx.h"
#endif
#include "wx/socket.h"
#define MY_SERVER_PORT 57343
class BroadcastFrame: public wxFrame
{
public:
BroadcastFrame(wxWindow* parent,wxWindowID id = -1);
virtual ~BroadcastFrame();
void Init_Datagram_Socket();
void OnUDPEvent(wxSocketEvent& event);
private:
//(*Handlers(BroadcastFrame)
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnMenuItemSendSelected(wxCommandEvent& event);
//*)
//(*Identifiers(BroadcastFrame)
static const long idMenuQuit;
static const long idMenuSend;
static const long idMenuAbout;
static const long ID_STATUSBAR1;
//*)
//(*Declarations(BroadcastFrame)
wxMenuItem* MenuItem3;
wxStatusBar* StatusBar1;
//*)
wxIPV4address m_BroadCastAddress; // For broadcast sending
wxIPV4address m_LocalAddress; // For listening
wxDatagramSocket* m_Listen_Socket;
DECLARE_EVENT_TABLE()
};
#endif // BROADCASTMAIN_H
Code: Select all
/***************************************************************
* Name: BroadcastMain.cpp
* Purpose: Code for Application Frame
* wxWidgets 2.8.12 sample to send and receive a UDP broadcast datagram
* Author: CJS ()
* Created: 2016-01-27
* Copyright: CJS ()
* License:
Excepting if sections are specifically annotated that other
conditions apply, the following MIT license shall apply:
Copyright (c) 2016 CJS
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
https://opensource.org/licenses/MIT
**************************************************************/
#include "BroadcastMain.h"
#include <wx/msgdlg.h>
//(*InternalHeaders(BroadcastFrame)
#include <wx/intl.h>
#include <wx/string.h>
//*)
// Event ID numbers:
enum
{
UDP_SOCKET = 200
};
// helper functions (standard wxSmith boilerplate)
enum wxbuildinfoformat
{
short_f, long_f
};
wxString wxbuildinfo(wxbuildinfoformat format)
{
wxString wxbuild(wxVERSION_STRING);
if (format == long_f )
{
#if defined(__WXMSW__)
wxbuild << _T("-Windows");
#elif defined(__UNIX__)
wxbuild << _T("-Linux");
#endif
#if wxUSE_UNICODE
wxbuild << _T("-Unicode build");
#else
wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
}
return wxbuild;
}
//(*IdInit(BroadcastFrame)
const long BroadcastFrame::idMenuQuit = wxNewId();
const long BroadcastFrame::idMenuSend = wxNewId();
const long BroadcastFrame::idMenuAbout = wxNewId();
const long BroadcastFrame::ID_STATUSBAR1 = wxNewId();
//*)
BEGIN_EVENT_TABLE(BroadcastFrame,wxFrame)
//(*EventTable(BroadcastFrame)
//*)
EVT_SOCKET(UDP_SOCKET, BroadcastFrame::OnUDPEvent)
END_EVENT_TABLE()
BroadcastFrame::BroadcastFrame(wxWindow* parent,wxWindowID id)
{
//(*Initialize(BroadcastFrame)
wxMenuItem* MenuItem2;
wxMenuItem* MenuItem1;
wxMenu* Menu1;
wxMenuBar* MenuBar1;
wxMenu* Menu2;
Create(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("id"));
MenuBar1 = new wxMenuBar();
Menu1 = new wxMenu();
MenuItem1 = new wxMenuItem(Menu1, idMenuQuit, _("Quit\tAlt-F4"), _("Quit the application"), wxITEM_NORMAL);
Menu1->Append(MenuItem1);
MenuItem3 = new wxMenuItem(Menu1, idMenuSend, _("Send"), _("Send a message"), wxITEM_NORMAL);
Menu1->Append(MenuItem3);
MenuBar1->Append(Menu1, _("&File"));
Menu2 = new wxMenu();
MenuItem2 = new wxMenuItem(Menu2, idMenuAbout, _("About\tF1"), _("Show info about this application"), wxITEM_NORMAL);
Menu2->Append(MenuItem2);
MenuBar1->Append(Menu2, _("Help"));
SetMenuBar(MenuBar1);
StatusBar1 = new wxStatusBar(this, ID_STATUSBAR1, 0, _T("ID_STATUSBAR1"));
int __wxStatusBarWidths_1[1] = { -1 };
int __wxStatusBarStyles_1[1] = { wxSB_NORMAL };
StatusBar1->SetFieldsCount(1,__wxStatusBarWidths_1);
StatusBar1->SetStatusStyles(1,__wxStatusBarStyles_1);
SetStatusBar(StatusBar1);
Connect(idMenuQuit,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&BroadcastFrame::OnQuit);
Connect(idMenuSend,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&BroadcastFrame::OnMenuItemSendSelected);
Connect(idMenuAbout,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&BroadcastFrame::OnAbout);
//*)
// Initialise the UDP datagram socket
Init_Datagram_Socket();
}
BroadcastFrame::~BroadcastFrame()
{
//(*Destroy(BroadcastFrame)
//*)
}
void BroadcastFrame::OnQuit(wxCommandEvent& event)
{
Close();
}
void BroadcastFrame::OnAbout(wxCommandEvent& event)
{
wxString msg = wxbuildinfo(long_f);
wxMessageBox(msg, _("Welcome to..."));
}
void BroadcastFrame::Init_Datagram_Socket()
{
// wxSocketBase::Initialize() may be necessary for wxWidgets versions
// <2.5.x, and for all versions if using secondary threads
// See https://wiki.wxwidgets.org/WxSocket
// See http://comp.soft-sys.wxwindows.narkive.com/vt9BEujR/wxsocketbase-initialize
wxSocketBase::Initialize();
m_LocalAddress.AnyAddress(); // Receive any address (0.0.0.0)
m_LocalAddress.Service(MY_SERVER_PORT); // port on which we listen
// Create the socket
m_Listen_Socket = new wxDatagramSocket(m_LocalAddress, wxSOCKET_REUSEADDR);
if (m_Listen_Socket->Error())
{
wxLogError(_("Could not open Datagram Socket\n\n"));
return;
}
else
{
///////////////////////////////////////////////////////////////////////////
// To send to a broadcast address, you must enable SO_BROADCAST socket
// option, in plain C this is:
// int enabled = 1;
// setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &enabled, sizeof(enabled));
// where sockfd is the socket descriptor (See http://linux.die.net/man/2/setsockopt)
// See also boxcarmiba Wed Aug 02, 2006
// at https://forums.wxwidgets.org/viewtopic.php?t=9410
static int enabled = 1;
m_Listen_Socket->SetOption(SOL_SOCKET, SO_BROADCAST, &enabled, sizeof(enabled) );
///////////////////////////////////////////////////////////////////////////
// Set types of event that you want to receive:
m_Listen_Socket->SetNotify(wxSOCKET_INPUT_FLAG);
// Enable the event notification:
m_Listen_Socket->Notify(true);
// Setup the event handler (UDP_SOCKET is our custom event ID)
// Note: Use EVT_SOCKET(UDP_SOCKET, BroadcastFrame::OnUDPEvent) in event table
m_Listen_Socket->SetEventHandler(*this, UDP_SOCKET);
}
}
// Responds to an event defined by an EVT_SOCKET table entry
void BroadcastFrame::OnUDPEvent(wxSocketEvent& event)
{
#define MAX_BUF_SIZE 1024
unsigned char buff[MAX_BUF_SIZE] = {0};
wxSocketBase *sock = event.GetSocket();
switch (event.GetSocketEvent())
{
case wxSOCKET_INPUT:
{ // Using blocking I/O (m_Listen_Socket NOT created with wxSOCKET_NOWAIT)
// - assumes that as an event occurred there must be data available
sock->Read(&buff, MAX_BUF_SIZE);
wxLogMessage(_("OnUDPEvent read: %hs\n"), buff);
break;
}
default:
wxLogMessage(_("OnUDPEvent received an unexpected event\n"));
} // switch
#undef MAX_BUF_SIZE
}
// Menu command to send a test UDP datagram, which should be received by this app
// and any other instances running on the local network:
void BroadcastFrame::OnMenuItemSendSelected(wxCommandEvent& event)
{
wxString wxmessage = wxString::Format(_T("Test using port %d"), MY_SERVER_PORT);
wxCharBuffer message = wxmessage.ToUTF8(); // used to get a const char* for SendTo
// Specify a broadcast IP, in this case "Limited Broadcast" on the local network:
m_BroadCastAddress.Hostname(_("255.255.255.255"));
m_BroadCastAddress.Service(MY_SERVER_PORT);
// Use same socket created for listening for sending:
m_Listen_Socket->SendTo(m_BroadCastAddress, message.data(), strlen(message.data()));
if (m_Listen_Socket->Error() )
{
wxLogMessage(_T("SendTo Error: %d"), m_Listen_Socket->LastError());
}
}
Code: Select all
/***************************************************************
* Name: BroadcastApp.h
* Purpose: Defines Application Class
* wxWidgets 2.8.12 sample to send and receive a UDP broadcast datagram
* Author: CJS ()
* Created: 2016-01-27
* Copyright: CJS ()
* License:
Excepting if sections are specifically annotated that other
conditions apply, the following MIT license shall apply:
Copyright (c) 2016 CJS
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
https://opensource.org/licenses/MIT
**************************************************************/
#ifndef BROADCASTAPP_H
#define BROADCASTAPP_H
#include <wx/app.h>
class BroadcastApp : public wxApp
{
public:
virtual bool OnInit();
};
#endif // BROADCASTAPP_H
Code: Select all
/***************************************************************
* Name: BroadcastApp.cpp
* Purpose: Code for Application Class
* wxWidgets 2.8.12 sample to send and receive a UDP broadcast datagram
* Author: CJS ()
* Created: 2016-01-27
* Copyright: CJS ()
* License:
Excepting if sections are specifically annotated that other
conditions apply, the following MIT license shall apply:
Copyright (c) 2016 CJS
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
https://opensource.org/licenses/MIT
**************************************************************/
#include "BroadcastApp.h"
//(*AppHeaders
#include "BroadcastMain.h"
#include <wx/image.h>
//*)
IMPLEMENT_APP(BroadcastApp);
bool BroadcastApp::OnInit()
{
//(*AppInitialize
bool wxsOK = true;
wxInitAllImageHandlers();
if ( wxsOK )
{
BroadcastFrame* Frame = new BroadcastFrame(0);
Frame->Show();
SetTopWindow(Frame);
}
//*)
return wxsOK;
}