Background
Break News
How to add local font to Tailwind Css and NextJS? - Tutorial Design Pattern? - Blockchain Technology, How to create own Bitcoin virtual currency - Zustand mordern management state - Design Pattern - Flyweight Pattern? - Docker Full training Topic

[Tips] Share free Source code about "Chat Application Using Server Client Architecture C++"

Thursday 24 December 2015
|
Read: Completed in minutes

[Tips] Share free Source code about "Chat Application Using Server Client Architecture C++"

Merry Xmas 2015 to all bloggers, developers, designers... ^_^ Today topic will be help you build one application with chat demo base on client-server architecture model! let's start now!


Download full source code on below link



Share free Source code about "Chat Application Using Server Client Architecture C++" - Webzone Tech Tips Zidane


In Computer science client-server is a software architecture model consisting of two parts, client systems and server systems, both communicating over a computer network or on the same computer. A client-server application is a distributed system made up of both client and server software.

Server, Client is one of advance tech skill for C++/MFC. So if you want to understand it clearly. Reading my source code, you can easy do it.

Code Server Side:


// ServerDlg.cpp : implementation file
// Last Modified: 21-12-2015
// ViLH / Zidane (huuvi168@gmail.com)

#include "stdafx.h"
#include "Server.h"
#include "ServerDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CServerDlg dialog

CServerDlg::CServerDlg(CWnd* pParent /*=NULL*/)
 : CDialog(CServerDlg::IDD, pParent)
{
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CServerDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 DDX_Control(pDX, IDC_EDIT_TEXT, m_txtMessage); 
 DDX_Control(pDX, IDC_LIST_MESSAGE, m_lstMessage);
}

BEGIN_MESSAGE_MAP(CServerDlg, CDialog)
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 //}}AFX_MSG_MAP
 ON_BN_CLICKED(IDCANCEL, &CServerDlg::OnBnClickedCancel)
 ON_BN_CLICKED(IDC_BUTTON_SEND, &CServerDlg::OnBnClickedButtonSend)
END_MESSAGE_MAP()


// CServerDlg message handlers

BOOL CServerDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // 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

 // TODO: Add extra initialization here

  
 // Thiết lập list control
 m_lstMessage.InsertColumn(0, L"My Message");
 m_lstMessage.SetColumnWidth(0, 300);

 // số dòng ban đầu:
 m_iRow = 0;

 // giới hạn text, hàn chế tràn buffer
 m_txtMessage.SetLimitText(100);

 // size control listControl
 m_cMySize.cx = 0;
 m_cMySize.cy = 30;
 
 // int num client connect (khởi tạo số lượng client đang connect)
 for (int i=0; i<NUMCLIENT; i++)
  m_sSockClient[i] = NULL;

 // init winsock
 WSAData wsa;
 WORD dwVersion = MAKEWORD(2,1); 
 int iResult = WSAStartup(dwVersion, &wsa);
 if (iResult != 0)
 {
  MessageBox(L"cannot start up win sock", L"Warning", MB_OK);
  return TRUE;
 }

 m_saServer.sin_addr.s_addr = htonl(INADDR_ANY);
 m_saServer.sin_family = AF_INET;
 m_saServer.sin_port = htons(PORT);

 m_ilen = sizeof(m_saServer);
 m_sSock = socket(AF_INET, SOCK_STREAM, NULL);

 if (bind(m_sSock, (SOCKADDR*)&m_saServer, m_ilen))
 {
  m_txtMessage.SetWindowText(L"Cannot bind ...");
  return TRUE;
 }

 m_txtMessage.SetWindowText(L"Server listening ...");

 listen(m_sSock, NUMCLIENT);  
 AfxBeginThread(&DoWork, 0);
  
 return TRUE;  // return TRUE  unless you set the focus to a control
}

// 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 CServerDlg::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();
    }
}

HCURSOR CServerDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}


void CServerDlg::OnBnClickedCancel()
{
    // TODO: Add your control notification handler code here
    OnCancel();
}

// **************************************************************
UINT DoWork(LPVOID p)
{
 CString sClientIPAddress;
 CString sMessage;
 
 CServerDlg *dlg = (CServerDlg*)AfxGetApp()->GetMainWnd();

 // Get Total client is free  
 int iNum = dlg->GetClientCount();
  
 // Get Data from client  
 int iData = 0;

 // Is Exists client connected  
 if (iNum >= 0)
 {
  iData = 1;
  dlg->m_sSockClient[iNum] = 
    accept( dlg->m_sSock, (sockaddr*) &(dlg->m_saServer), &(dlg->m_ilen) );

// Get IP from client connecting  
  sClientIPAddress = inet_ntoa(dlg->m_saServer.sin_addr); 

// Cannot accept connect with client 
  if (dlg->m_sSockClient[iNum] == INVALID_SOCKET)
   dlg->m_txtMessage.SetWindowText(L"Error Accept");  
  else
  {
  // Create Thread for every client  
           AfxBeginThread(&DoWork, 0); 
      
   sMessage.Append(L"IP: " + sClientIPAddress + L" Connected!");
   sMessage.AppendFormat(L" - Num = %d", iNum);

   dlg->m_lstMessage.InsertItem(dlg->m_iRow++, sMessage);

   // scroll for view (cuộn thanh cuộn xuống cho dễ nhìn)
   dlg->m_lstMessage.Scroll(dlg->m_cMySize); 
   
   // Receive data from another IP 
   char cbuff[101];
   while (iData != SOCKET_ERROR)
   {
     memset(cbuff, 0x0, 101);
     iData = recv(dlg->m_sSockClient[iNum], cbuff, 101, 0);
     dlg->SetForegroundWindow();

    sMessage = L"";
    if (iData != SOCKET_ERROR)
    {
     // chèn câu chat vào list control
     sMessage = cbuff;
     dlg->m_lstMessage.InsertItem(dlg->m_iRow++, sMessage);
       dlg->m_lstMessage.Scroll(dlg->m_cMySize);
       dlg->SendMsgToAllClient(dlg->m_sSockClient[iNum], cbuff);
    }
   }

   //  client "disconnect" khi gặp lỗi .. / disconnect   
   sMessage.Append(L"Client: " + sClientIPAddress + L" Disconnected!");
   dlg->m_lstMessage.InsertItem(dlg->m_iRow++, sMessage);
   dlg->m_lstMessage.Scroll(dlg->m_cMySize);

   dlg->ConvertToChar(sMessage, cbuff, 101);

   dlg->SendMsgToAllClient(dlg->m_sSockClient[iNum], cbuff);
   dlg->m_lstMessage.Scroll(dlg->m_cMySize);
   dlg->m_sSockClient[iNum] = NULL;// release lại 1 kết nối 

   closesocket(dlg->m_sSockClient[iNum]);  
  }
 }

 AfxEndThread(0);
 return 0;
}

// **************************************************************
// lấy số lượng toàn bộ client đang rãnh
int CServerDlg::GetClientCount(void)
{
 for (int i=0; i<NUMCLIENT; i++)
 {
  if (m_sSockClient[i] == NULL)
   return i;
 }
 return -1;
}

// **************************************************************
void CServerDlg::SendMsgToAllClient(SOCKET sock, char* message)
{
 for (int i=0; i<NUMCLIENT; i++)
 {
  // Check send message to client.
  // kiểm tra nếu tồn tại client và không phải chính bản thân thì send message
  if (m_sSockClient[i] != NULL && m_sSockClient[i] != sock)
   send (m_sSockClient[i],message, 101, 0);
 }
}

// **************************************************************
// chuyển đổi CString to char*
char* CServerDlg::ConvertToChar(const CString& s, char* pAnsiString, int bufsize)
{
 wcstombs(pAnsiString,(LPCTSTR) s, bufsize);
 return pAnsiString;
}

// **************************************************************
// server disconnect: giải phóng ~>
CServerDlg::~CServerDlg()
{ 
    for (int i = 0; i<NUMCLIENT; i++)
      if (m_sSockClient[i] != NULL) // Client Exists  (tồn tại client)
         // chỉ send đến những client chưa disconnect          
         send (m_sSockClient[i], "Server Disconnected", 100, 0); 
          

    WSACleanup();
}

// **************************************************************
// Send Data with Button (Send dữ liệu tới client)
void CServerDlg::OnBnClickedButtonSend()
{
 // TODO: Add your control notification handler code here
 
 CString sMessage;
 CString sAllMessage = L"Server: ";

 m_txtMessage.GetWindowText(sMessage);
 sAllMessage.Append(sMessage);

 m_txtMessage.SetWindowText(L"");
 m_lstMessage.InsertItem(m_iRow++ , sAllMessage);

 // scroll theo size 
 m_lstMessage.Scroll(m_cMySize);

 char buff[101];
 ConvertToChar(sAllMessage, buff, 101);
 for (int i=0; i<NUMCLIENT; i++)
     if (m_sSockClient[i])
  send(m_sSockClient[i], buff, 101, 0);
}





Code Client Side


// ClientDlg.cpp : implementation file
//

/*******************************************************
Author: VịLH / Zidane // huuvi168@gmail.com
*******************************************************/

#include "stdafx.h"
#include "Client.h"
#include "ClientDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
 CAboutDlg();

// Dialog Data
 enum { IDD = IDD_ABOUTBOX };

 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CClientDlg dialog




CClientDlg::CClientDlg(CWnd* pParent /*=NULL*/)
 : CDialog(CClientDlg::IDD, pParent)
{
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CClientDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 DDX_Control(pDX, IDC_EDIT_IPADDRESS, m_txtIPAddress);
 DDX_Control(pDX, IDC_EDIT_MESSAGE, m_txtMessage);
 DDX_Control(pDX, IDC_LIST_MESSAGE, m_lstMessage);
 DDX_Control(pDX, IDC_EDIT_USERNAME, m_sName);
}

BEGIN_MESSAGE_MAP(CClientDlg, CDialog)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 //}}AFX_MSG_MAP
 ON_BN_CLICKED(IDC_BUTTON_CONNECT, &CClientDlg::OnBnClickedButtonConnect)
 ON_BN_CLICKED(IDC_BUTTON_DISCONNECT, &CClientDlg::OnBnClickedButtonDisconnect)
 ON_BN_CLICKED(IDCANCEL, &CClientDlg::OnBnClickedCancel)
 ON_BN_CLICKED(IDC_BUTTON_SEND, &CClientDlg::OnBnClickedButtonSend)
END_MESSAGE_MAP()


// CClientDlg message handlers

BOOL CClientDlg::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)
 {
  BOOL bNameValid;
  CString strAboutMenu;
  bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
  ASSERT(bNameValid);
  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

 // TODO: Add extra initialization here
 
 // Settings default Value
 m_iRow = 0;

 m_txtIPAddress.SetWindowText(L"10.0.0.2");
 m_txtMessage.SetLimitText(100);
 m_lstMessage.InsertColumn(0, L"Client Message");
 m_lstMessage.SetColumnWidth(0, 300);

 m_cMySize.cx = 0;
 m_cMySize.cy = 30;


 // Name init
 m_sName.SetWindowText(L"HuuVi");

 m_bIsConnected = FALSE;
 GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(FALSE);
 GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);
 GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(TRUE);

 return TRUE;  // return TRUE  unless you set the focus to a control
}

void CClientDlg::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 CClientDlg::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 CClientDlg::OnQueryDragIcon()
{
 return static_cast<HCURSOR>(m_hIcon);
}


// ************************************************************
void CClientDlg::OnBnClickedButtonConnect()
{
 // TODO: Add your control notification handler code here
 CString sAddress;
 m_txtIPAddress.GetWindowText(sAddress);

 char cAddress[50];
 ConvertToChar(sAddress, cAddress, 50);

 // Init winsock
 WSAData wsa;
 WORD dwVersion = MAKEWORD(2,1); 
 int iResult = WSAStartup(dwVersion, &wsa);
 if (iResult != 0)
 {
  MessageBox(L"cannot start up win sock", L"Warning", MB_OK);
  return;
 }

 m_saClient.sin_addr.s_addr = inet_addr(cAddress);
 m_saClient.sin_family = AF_INET;
 m_saClient.sin_port = htons(PORT);

 m_sSock = socket(AF_INET, SOCK_STREAM, 0);

 GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(FALSE);
 GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(TRUE);
 GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);

 m_bIsConnected = TRUE;

 // AfxBeginThread(&DoWork, 0);
 CreateThread(0,0,(LPTHREAD_START_ROUTINE)DoWork, (void *)0, 0, 0);
}

// **************************************************************
// Convert CString to char*
char* CClientDlg::ConvertToChar(const CString& s, char* pAnsiString, int bufsize)
{
 wcstombs(pAnsiString,(LPCTSTR) s, bufsize);
 return pAnsiString;
}

// **************************************************************
UINT DoWork(LPVOID p)
{
 CClientDlg *dlg = (CClientDlg*)AfxGetApp()->GetMainWnd();

 CString sAddress;
 dlg->m_txtIPAddress.GetWindowText(sAddress);

 // Connect to server ..
 while ((connect(dlg->m_sSock, 
           (sockaddr*)&dlg->m_saClient, sizeof(dlg->m_saClient))  ) 
            && dlg->m_bIsConnected == TRUE)
 {
  dlg->m_txtMessage.SetWindowText(L"Please Wait ...");

  char cbuf[50];
  memset(cbuf, 0x0, NULL);
  dlg->ConvertToChar(sAddress, cbuf, 50);
  dlg->m_saClient.sin_addr.s_addr = inet_addr(cbuf);
 }

 CString sMessage;
 CString sClientAddress;
 char buff[101];

 if (dlg->m_bIsConnected == TRUE) // connect succeed!
 {
  sClientAddress = inet_ntoa(dlg->m_saClient.sin_addr); 
   sMessage.Append(L"--> Client: " + sClientAddress + L" Connected!"); 

  dlg->GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(TRUE);

  dlg->m_lstMessage.InsertItem(dlg->m_iRow++, sMessage);

  dlg->SetForegroundWindow();

  int iData = 1; // Data receive from server and another client
  
  // connect succeed and prepare receive data
  while (iData != SOCKET_ERROR)
  {
   iData = recv(dlg->m_sSock, buff, 101, 0);
   dlg->SetForegroundWindow();

   if (iData != SOCKET_ERROR)
   {
      sMessage = buff;
      dlg->m_lstMessage.InsertItem(dlg->m_iRow++, sMessage);
      dlg->m_lstMessage.Scroll(dlg->m_cMySize);
   }

   if (dlg->m_bIsConnected == FALSE)
    break;
  }
 }
  
 sMessage = L"Client: " + sClientAddress  + L" Disconnected!";

 dlg->ConvertToChar(sMessage, buff, 101);
 send (dlg->m_sSock, buff, 101, 0);
 closesocket(dlg->m_sSock);
 

 AfxEndThread(0);
 return 0;
}

// ********************************************************
void CClientDlg::OnBnClickedButtonDisconnect()
{
 // TODO: Add your control notification handler code here

 m_bIsConnected = FALSE;
 GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(TRUE);
 GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(FALSE);
 GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);

 CString sMessage = L"Disconnected";
 m_lstMessage.InsertItem(m_iRow++, sMessage);
 m_txtMessage.SetWindowText(L"");
 
 closesocket(m_sSock);
}

// ********************************************************
// exit
void CClientDlg::OnBnClickedCancel()
{
 // TODO: Add your control notification handler code here
 OnCancel();
}

// ********************************************************
CClientDlg::~CClientDlg()
{
 m_bIsConnected = FALSE;
 closesocket(m_sSock);
}

// **************************************************************
void CClientDlg::OnBnClickedButtonSend()
{
 // TODO: Add your control notification handler code here
 
 CString sMessage;
 CString sAllMessage;

 m_sName.GetWindowText(sAllMessage);
 m_txtMessage.GetWindowText(sMessage);
 sAllMessage.Append(L":" + sMessage);

 // Insert message into client 
 m_lstMessage.InsertItem(m_iRow++, sAllMessage);
 m_lstMessage.Scroll(m_cMySize);
 m_txtMessage.SetWindowText(L"");

 char cbuff[101];
 ConvertToChar(sAllMessage, cbuff, 101);
 send (m_sSock, cbuff, 101, 0); 
}

Are you interested in topic [Tips] Share free Source code about "Chat Application Using Server Client Architecture C++" from Webzone Tech Tips? If you have any thoughts or questions, please share them in the comment section below. I would love to hear from you and chat about it

Webzone Tech Tips Zidane


🙇🏼 We Appreciate Your Comments and Suggestions - Webzone - all things Tech Tips web development 🙇🏼
Popular Webzone Tech Tips topic maybe you will be like it - by Webzone Tech Tips - Zidane
As a student, I found Blogspot very useful when I joined in 2014. I have been a developer for years . To give back and share what I learned, I started Webzone, a blog with tech tips. You can also search for tech tips zidane on Google and find my helpful posts. Love you all,

I am glad you visited my blog. I hope you find it useful for learning tech tips and webzone tricks. If you have any technical issues, feel free to browse my posts and see if they can help you solve them. You can also leave a comment or contact me if you need more assistance. Here is my blog address: https://learn-tech-tips.blogspot.com.

My blog where I share my passion for web development, webzone design, and tech tips. You will find tutorials on how to build websites from scratch, using hot trends frameworks like nestjs, nextjs, cakephp, devops, docker, and more. You will also learn how to fix common bugs on development, like a mini stackoverflow. Plus, you will discover how to easily learn programming languages such as PHP (CAKEPHP, LARAVEL), C#, C++, Web(HTML, CSS, javascript), and other useful things like Office (Excel, Photoshop). I hope you enjoy my blog and find it helpful for your projects. :)

Thanks and Best Regards!
Follow me on Tiktok @learntechtips and send me a direct message. I will be happy to chat with you.
Webzone - Zidane (huuvi168@gmail.com)
I'm developer, I like code, I like to learn new technology and want to be friend with people for learn each other
I'm a developer who loves coding, learning new technologies, and making friends with people who share the same passion. I have been a full stack developer since 2015, with more than years of experience in web development.
Copyright @2022(November) Version 1.0.0 - By Webzone, all things Tech Tips for Web Development Zidane
https://learn-tech-tips.blogspot.com