Software & Finance





Visual C++ Socket Programming - UDP Broadcast Server Application and Client Application





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.

 


Source Code


// UDPClientDlg.h : header file

//

 

#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<WPARAM>(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<HCURSOR>(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 <stdio.h>

#include <tchar.h>

#include <winsock2.h>

#include <string>

#include <iostream>

#include <atlbase.h>

 

 

int _tmain(int argc, TCHAR* argv[])

{

   

    if(argc < 3)

    {

        std::cout << "Error in Syntax: UDPServer.exe <port no> <msg>";

        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

Output


 

c:\> UDPServer.exe 1818 "Thanks for using softwareandfinance.com by Kathir"