Click here to Skip to main content
15,867,756 members
Articles / Desktop Programming / MFC
Article

Barry's Chat System

Rate me:
Please Sign up or sign in to vote.
4.91/5 (8 votes)
24 Nov 20025 min read 139.9K   7.5K   57   21
Barry's Chat System

Sample Image - BarrysChatSystem.gif

Introduction

This article demonstrates the technique of creating a chat system. The article contains a chat server and a chat client, each performs different tasks and cannot be used interchangeably. Both client and server use Windows sockets for the purpose of connecting and sending lines of text between themselves. You can use the server and client either on your machine or over a private LAN or network to chat.

NOTE: I do not have access to either a LAN or network, hence this software was only tested in "local loop" on my machine, anyone testing the software over a network can please send the test results through E-Mail to me.

How to use

Preparing to use ChatServer & ChatClient

  • Download the ChatServer & ChatClient source code
  • Unzip ChatServer & ChatClient source code
  • Start Visual Studio
  • Build the ChatServer & ChatClient executables
  • Exit Visual Studio

To use the ChatServer and ChatClient on your machine in what is know as "Local Loop", do the following:

Starting ChatServer

  • Start ChatServer (executable is in ChatServer\Debug folder)
  • Keep the port no. 0 and click Ok (note: if you change the port no. the same no. must be used when connecting through ChatClient)
  • Port no. can be between 0 to 1499 (this is useful in cases where the port no. is in use by another application on the server system
  • Note: Even though the port no. input is 0, it is in reality 1500 + x (x stands for the port no. input by you, 0 in this case)

Starting ChatClient

  1. Start ChatClient (executable is in ChatClient\Debug folder)
  2. From the menu, select Connection->Connect (or click on the Connect button)
  3. Logon form will be displayed
  4. In the server box type 127.0.0.1
  5. In the nickname box type any name (should be different for each invocation of ChatClient)
  6. In the port no. box type 0 (remember we had started the ChatServer with 0 as port no.)
  7. Click Ok
  8. Repeat steps 1 thru 7 above to start another ChatClient but with a different nickname. You can start as many ChatClients as you want, restricted by available memory.
  9. Chat to your hearts content, with yourself of course.

To use ChatServer and ChatClient on a network do the following, carry out the steps in the "Preparing to use ChatServer & ChatClient" above.

  • Copy ChatServer executable on a server system
  • Copy ChatClient executables on machines from where you want users to chat
  • Start ChatServer on the server system, refer the "Starting ChatServer" section above
  • Start ChatClient on the machines where the ChatClients were copied, refer the "Starting ChatClient" section above, but remember, in the server box on the logon form, you have to type the name or IP address of the server system on which the ChatServer is running (not 127.0.0.1) and port no. as applicable

Caution

If you copy ChatServer and ChatClient executables on machines that do not have Visual Studio setup, the executables may not run since MFC is not installed by default on the Windows operating system.

If the installable versions of ChatServer and ChatClient are available for download in the download section at the top, you can install both on any machine running Windows 9x /Windows 2000 / Windows XP, since the Installable versions have MFC included.

I may not upload the installable versions at present because of their huge size (1.2Mb each) and to be very frank I cannot afford it at present, maybe over a period of time, if there is demand for the same.

What's missing

  • No colored text for chatting
  • No variable fonts for chatting
  • Single chat room
  • No threads used in the source

Maybe in a later version the above could be incorporated, presently under testing.

Note for developers

Most important code for both the server and client is in the classes CChatServerDoc and CChatClientDoc, you would well concentrate on these two classes.

A CObject class named CMsg is used in both server and client to send and receive messages back and forth, which are then unassembled by the receiver (server or client). CMsg class has the following members:

  • Code (to indicate the type of message)
  • m_strText (message text)
  • m_bClose (sent when the client is disconnecting or shutting down)

Following is a list of codes sent by both server and client (you can have your own codes as the need maybe):

#define JOINING_CHAT          1
#define LEAVING_CHAT          2
#define SENDING_CHATTERS_LIST 3
#define SENDING_NICKNAME      4
#define NORMAL_MESSAGE        5
#define DUPLICATE_NICKNAME    6

How it works

After you start the server by inputting port no. and clicking Ok, a socket is created for listening for incoming connect request, using the following code in the member function OnNewDocument()

m_pSocket = new CListeningSocket(this);
if (m_pSocket->Create(Dialog.m_nPort+1500))
{
    if (m_pSocket->Listen())
        return TRUE;
}

When a new connect request is received from a client, the member function OnAccept in the class CListeningSocket is notified by the system. OnAccept then calls ProcessPendingAccept function in class CChatServerDoc as show below:

void CListeningSocket::OnAccept(int nErrorCode)
{
    CSocket::OnAccept(nErrorCode);
    m_pDoc->ProcessPendingAccept();
}

In the ProcessPendingAccept function, a new socket (CClientSocket) is created for the new client and the created socket is added to the pointer list CPtrList, which is a kind of array. We use the pointer list all throughout the program to retrieve the socket for sending or receiving messages. The system then reads the incoming message in the member function OnReceive in the CClientSocket which in turn calls ProcessPendingRead sending to it the client socket, which sends the message, as shown below:

void CClientSocket::OnReceive(int nErrorCode)
{
     CSocket::OnReceive(nErrorCode);
     m_pDoc->ProcessPendingRead(this);
}

Inside ProcessPendingRead the CMsg object sent by the client is unassembled and based on Code of the message, action is taken as appropriate.

When a client disconnects or exits by selecting from menu, File->Exit, a message is sent to the server with m_bClose set to TRUE. Server receives the message and closes the client socket as shown below:

void CChatServerDoc::CloseSocket(CClientSocket* pSocket)
{
    // Close the Client Socket
    pSocket->Close();
    POSITION pos,temp;
    for(pos = m_connectionList.GetHeadPosition(); pos != NULL;)
    {
        temp = pos;
        // Search for the Socket in the Pointer List
        CClientSocket* pSock = 
           (CClientSocket*)m_connectionList.GetNext(pos);
        if (pSock == pSocket)
        {
            // Found it , so remove it from the Pointer list
            // so that no more messages are sent to that Client Socket
            m_connectionList.RemoveAt(temp);
            break;
        }
    }
    UpdateConnections();
    delete pSocket;
    if(m_connectionList.GetCount() == 0)
        m_msgList.RemoveAll();
}

If you exit the server by selecting from the menu, File->Exit, and if there are clients connected, all the clients are notified by the server that it has shut down and all the CClientSocket(s) are closed. This also prevents the clients from crashing. Following is the code which carries out the task of closing the client sockets.

void CChatServerDoc::DeleteContents()
{
     // You must initilize m_pSocket to NULL in the Constructor of 
     // CChatServerDoc else the server will crash at the start
     if(m_pSocket == (CListeningSocket*)NULL)
        return;

    // Delete the Listening Socket
    delete m_pSocket;
    m_pSocket = NULL;
    
    CString temp;
    if (temp.LoadString(IDS_SERVERSHUTDOWN))
        m_msgList.AddTail(temp);

    while(!m_connectionList.IsEmpty())
    {
     // Get a Pointer to the Client Socket
      CClientSocket* pSocket = 
        (CClientSocket*)m_connectionList.RemoveHead();
      CMsg* pMsg = AssembleMsg(pSocket , NORMAL_MESSAGE);
      //Set Code for Closing
        pMsg->m_bClose = TRUE;
      // Send Server ShutDowm message to the Client
      SendMsg(pSocket, pMsg);

      if (!pSocket->IsAborted())
      {
         // ShutDown the Client
         pSocket->ShutDown();
         BYTE Buffer[50];
         while (pSocket->Receive(Buffer,50) > 0);
         // Delete the Client Socket
         delete pSocket;
      }
   }

   m_msgList.RemoveAll();

   if (!m_viewList.IsEmpty())
      Message("");

   CDocument::DeleteContents();
}

Have fun, chat to your heart's content, but don't blame me. I developed this by modifying MSDN Sample Chatter & Chatsvr for fun sake.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
India India
Nothing to boast about

Comments and Discussions

 
GeneralHello....I Need your help. Pin
Pardi Banjarnahor15-Jan-08 18:13
Pardi Banjarnahor15-Jan-08 18:13 
GeneralClient doesn't receive massage Pin
Oksamuta6-Jul-07 2:49
Oksamuta6-Jul-07 2:49 
GeneralRe: Client doesn't receive massage Pin
Barretto VN6-Jul-07 4:19
Barretto VN6-Jul-07 4:19 
Generalthanks! Pin
seagal18-May-07 23:55
seagal18-May-07 23:55 
Very nice!Smile | :)
GeneralNice! But... Pin
Nvng YA24-Jan-07 3:24
Nvng YA24-Jan-07 3:24 
QuestionWHY OLE ? Pin
justtforfun22-Jun-06 5:36
justtforfun22-Jun-06 5:36 
QuestionMinor bug. Needs a fix. Anyone have ideas? Pin
Paul Groetzner13-Apr-04 2:47
Paul Groetzner13-Apr-04 2:47 
AnswerRe: Minor bug. Needs a fix. Anyone have ideas? Pin
jorgerulez11-Dec-06 1:12
jorgerulez11-Dec-06 1:12 
GeneralBarry Chat System Pin
JChong16-Sep-03 21:51
JChong16-Sep-03 21:51 
GeneralBuild Problems in VC7 Pin
Barretto VN28-Jun-03 22:05
Barretto VN28-Jun-03 22:05 
GeneralVC 7 Does not work Pin
Bulent YILDIRIM20-Mar-03 20:34
Bulent YILDIRIM20-Mar-03 20:34 
GeneralRe: VC 7 Does not work Pin
Barretto VN1-Apr-03 21:00
Barretto VN1-Apr-03 21:00 
GeneralVery Good Pin
Anil Nagubadi18-Jan-03 13:30
Anil Nagubadi18-Jan-03 13:30 
GeneralRe: Very Good Pin
Barretto VN12-Feb-03 0:39
Barretto VN12-Feb-03 0:39 
GeneralChat With US DI Pin
DCUtility26-Nov-02 16:55
professionalDCUtility26-Nov-02 16:55 
GeneralRe: Chat With US DI Pin
mirano9-Jan-04 12:41
mirano9-Jan-04 12:41 
GeneralRelease build doesn't link! Pin
Chris Hambleton25-Nov-02 3:42
Chris Hambleton25-Nov-02 3:42 
GeneralRe: Release build doesn't link! Pin
Anonymous4-Dec-02 16:14
Anonymous4-Dec-02 16:14 
GeneralRe: Release build doesn't link! Pin
Subhobroto17-Mar-07 5:12
Subhobroto17-Mar-07 5:12 
GeneralTHE DOWNLOAD DOES NOT WORK! Pin
eslea25-Nov-02 2:43
eslea25-Nov-02 2:43 
GeneralRe: THE DOWNLOAD DOES NOT WORK! Pin
eagle_xmw25-Nov-02 3:14
eagle_xmw25-Nov-02 3:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.