April 2012 - Technology - Sample UDP Broadcast Server in C++
I have come up with a UDP Broadcast Server Application that sends a data packet to all machines connected in the local network on a particular port. The server application is a Win32 Console Application and Client application is MFC Dialog based application.
You can run the client application in any numbers of machines connected in the local network. Once you execute a message from UDP broadcast server application, all clients will get in one shot.
The complete source code and executable links are given at the bottom of this page.
// #pragma once #include "afxwin.h" // CUDPClientDlg dialog class CUDPClientDlg : public CDialog { // Construction public: CUDPClientDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data enum { IDD = IDD_UDPCLIENT_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected: void StartListening(); HICON m_hIcon; // Generated message map functions virtual BOOL OnInitDialog(); afx_msg void OnTimer(UINT_PTR nIDEvent); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() public: SOCKET m_clientsocket; CString m_recvData; CEdit m_editCtrl; afx_msg void OnBnClickedOk(); int m_portno; afx_msg void OnBnClickedCancel(); }; #include "stdafx.h" #include "UDPClient.h" #include "UDPClientDlg.h" // CUDPClientDlg dialog CUDPClientDlg::CUDPClientDlg(CWnd* pParent /*=NULL*/) : CDialog(CUDPClientDlg::IDD, pParent) , m_recvData(_T("")) , m_portno(1818) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CUDPClientDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_recvData); DDX_Control(pDX, IDC_EDIT1, m_editCtrl); DDX_Text(pDX, IDC_EDIT3, m_portno); } BEGIN_MESSAGE_MAP(CUDPClientDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_TIMER() //}}AFX_MSG_MAP ON_BN_CLICKED(IDOK, &CUDPClientDlg::OnBnClickedOk) ON_BN_CLICKED(IDCANCEL, &CUDPClientDlg::OnBnClickedCancel) END_MESSAGE_MAP() // CUDPClientDlg message handlers BOOL CUDPClientDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon return TRUE; // return TRUE unless you set the focus to a control } void CUDPClientDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CUDPClientDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this function to obtain the cursor to display while the user drags // the minimized window. HCURSOR CUDPClientDlg::OnQueryDragIcon() { return static_cast (m_hIcon); } void CUDPClientDlg::OnBnClickedOk() { StartListening(); SetTimer(0x1, 100, NULL); GetDlgItem(IDOK)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT3)->EnableWindow(FALSE); //OnOK(); } void CUDPClientDlg::StartListening() { UpdateData(TRUE); m_clientsocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if(m_clientsocket == -1) { MessageBox("Error in creating socket"); return; } //struct hostent *hostentry = gethostbyname(m_serveraddr); //char *pipaddr = inet_ntoa (*(struct in_addr *)*hostentry->h_addr_list); //UDPserveraddr.sin_addr.s_addr = inet_addr(pipaddr); SOCKADDR_IN UDPserveraddr; memset(&UDPserveraddr,0, sizeof(UDPserveraddr)); UDPserveraddr.sin_family = AF_INET; UDPserveraddr.sin_port = htons(m_portno); UDPserveraddr.sin_addr.s_addr = INADDR_ANY; int len = sizeof(UDPserveraddr); if(bind(m_clientsocket, (SOCKADDR*)&UDPserveraddr,sizeof(SOCKADDR_IN)) < 0) { MessageBox("ERROR binding in the server socket"); return; } } void CUDPClientDlg::OnTimer(UINT_PTR nIDEvent) { fd_set fds; struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 100; FD_ZERO(&fds); FD_SET(m_clientsocket, &fds); int rc = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout); if(rc > 0) { char rbuf[1024]; SOCKADDR_IN clientaddr; int len = sizeof(clientaddr); if(recvfrom(m_clientsocket,rbuf, 1024, 0, (sockaddr*)&clientaddr, &len) > 0) { for(int i = 1024; i >= 1; i--) { if(rbuf[i] == '\n' && rbuf[i - 1] == '\r') { rbuf[i-1] = '\0'; break; } } char *p = inet_ntoa(clientaddr.sin_addr); int serverportno = ntohs(clientaddr.sin_port); CString rData; rData.Format("%s\r\nBroadcast Server: %s \r\n%s\r\n\r\n", (const char*)CTime::GetCurrentTime().Format("%B %d, %Y %H:%M:%S"), p, rbuf); m_recvData = rData + m_recvData; UpdateData(FALSE); } } CDialog::OnTimer(nIDEvent); } void CUDPClientDlg::OnBnClickedCancel() { ShellExecute(NULL, _T("open"), _T("http://www.softwareandfinance.com"), NULL, NULL, SW_SHOWNORMAL); OnCancel(); } // UDPServer.cpp : Defines the entry point for the console application. // #include #include #include #include #include #include int _tmain(int argc, TCHAR* argv[]) { if(argc < 3) { std::cout << "Error in Syntax: UDPServer.exe "; return 0; } int portno = ::_wtoi(argv[1]); USES_CONVERSION; char *p = W2A(argv[2]); WORD w = MAKEWORD(1,1); WSADATA wsadata; ::WSAStartup(w, &wsadata); SOCKET s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if(s == -1) { std::cout << "Error in creating socket"; return 0; } char opt = 1; setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&opt, sizeof(char)); SOCKADDR_IN brdcastaddr; memset(&brdcastaddr,0, sizeof(brdcastaddr)); brdcastaddr.sin_family = AF_INET; brdcastaddr.sin_port = htons(portno); brdcastaddr.sin_addr.s_addr = INADDR_BROADCAST; int len = sizeof(brdcastaddr); char sbuf[1024]; sprintf(sbuf, "%s\r\n", p); int ret = sendto(s, sbuf, strlen(sbuf), 0, (sockaddr*)&brdcastaddr, len); if(ret < 0) { std::cout << "Error broadcasting to the clients"; } else if(ret < strlen(sbuf)) { std::cout << "Not all data broadcasted to the clients"; } else { std::cout << "Broadcasting is done"; } ::closesocket(s); return 0; }
Click here to download the Visual C++ source code and executable file
c:\> UDPServer.exe 1818 "Thanks for using softwareandfinance.com by Kathir"