Blue Theme Orange Theme Green Theme Red Theme
 
Home | Forums | ASP.NET 2.0 Tutorials | Web Services | How Do I...? | Class Browser | WPF Quick Starts | Advertise with Us
 | Consulting  
Submit an Article Submit a Blog 
 Jump to
Skip Navigation Links
TechnologyExpand Technology
WebsiteExpand Website
6 Months Free & No Setup Fees ASP.NET Hosting!
Search :       Advanced Search »
Home » VC++.NET » Multithreaded N-N ChatApplication using Socket Programming

Multithreaded N-N ChatApplication using Socket Programming

Multithreaded N-N Chat Application is LAN based application. where any number of users can login and take part in chating.This is not a general chat room where a message sent, gets displayed to each person currently loged in. You can send message to only the intended receipent where you are assured that nobody other will get the message,except the main server where you will see all the messages sent through this application.

Page Views : 16083
Downloads : 605
Rating :
 Rate it
Level : Intermediate
   Print Read/Post comments Post a comment  Similar Articles  
   Email to a friend  Bookmark  Author's other articles  
Download Files:
Download.zip
 
 
Nevron Gauge for SharePoint
Become a Sponsor
 Tag Cloud
 Latest Jobs
More ... 
 Latest Interview Questions
More ... 

Introduction

Multithreaded N-N Chat Application is LAN based application. where any number of users can login and  take part in chating. This is not a general chat room where a message sent, gets displayed to each person currently loged in. You can send message to only the intended receipent where you are assured that nobody other will get the message, except the main server where you will see all the messages sent through this application.  

ChatApplication

Background

Here I have tried to show the use of threading and socket programming. If the user has some basic idea of threading and socket programming independant of implementation details it will be helpful to understand the logical sequance. 

How to use it?

You will find two folders in the .zip file.  One is client and the other is server.  Copy this project on the computer which you want to work as server. Copy the client project on all other computers which you want to work as clients. Keep in mind that you can have both server and any number of clients on the same computer too. Now first start the server by pressing the "StartServer" button. Now start the client application. Provide the IP address of the server in the text box named "server". Provide the user name with which you want to login in "Name" textbox. Then press the connect button. You will see your listbox getting filled wait for it to be completed. Once it is over, select any name from the list, write message in the "WriteMessage" box and press send button. At last when you want to get out from the chat click "logout" button rather than directly closing the application by clicking the "close" button.

Using the code

Basicaly the application has some predefined codes which are being passed as header information with each message and are used to identify the type of the message and based on the type, it will be processed differently.

You will be able to see all the code at server as all the messages are being dispalyed at server along with the header information. This codes will be useful for understanding the program flow.

Next, I have one thread continously running and listing at port - 70  for new connection requests and as the client is accepted, one another thread is created dynamicaly at runtime private for that client which will handle all the interaction to that client. That thread will continously read data from that client and send to the server. So, at server we have one main thread accepting the clients and N number of client represantative threads dealing with its client only.

Server maintains the Collection object storing each client at any moment it is little tricky to maintain this list when some client logs out.

At the client application, once the connection is established, one thread is created which continously reads data from the server and processes the data according to the header information. Normaly execution at client will be in this thread only.

This is the main reading thread running at server. Check differnt codes being used and processng according to the codes used. 

static void readThrd()
 {
  int thrdno;
   thrdno = curclno;
   NetworkStream *readstream = cl->GetStream();
  while(1)
  {
       Byte buff [] = new Byte[100];
       int len=0;
       try {
       len = readstream->
       Read(buff,0,buff->Length);
       }
       catch(Exception *e) {
       System::Windows::Forms::MessageBox::Show(e->Message);
       }
       richTextBox1->Text = String::Concat(richTextBox1->Text,listBox1->Items->get_Item(thrdnos[thrdno]/*thrdno*/)->ToString());
       richTextBox1->Text = String::Concat(richTextBox1->Text,S" : "); richTextBox1->Text = String::Concat(richTextBox1->Text,System::Text::Encoding::ASCII->GetString(buff,0,buff->Length));
       String *mesg;
       String *tmpsub;
       tmpsub = S"";
       mesg=S"";
       mesg = System::Text::Encoding::ASCII->GetString(buff,0,len);
       try {
           tmpsub = mesg->Substring(0,5);
       }
       catch(Exception *e) {
           System::Windows::Forms::MessageBox::Show(e->Message);
       }
       if(!String::Compare(tmpsub,S"%%%01")) //Normal Message for other client
       {
            int index,listboxind;
            int length;
            index = mesg->IndexOf('$');
            String *sub2 = "";
            sub2= mesg->Substring(index+1,(mesg->Length-index-1));
            try {
                 if(listBox1->Items->Contains(mesg->Substring(index+1,(mesg->Length-index-1))->ToString()))
   listboxind = listBox1->Items->IndexOf(mesg->Substring(index+1,(mesg->Length-index-1))->ToString());
                 length=0;
                 length=sub2->Length;
            }
            catch(Exception *e)
            {
  continue;
     }
            IEnumerator *en = sockList->GetEnumerator();
            en->MoveNext();
            for(int i=0;iMoveNext();
            }
            NetworkStream *sndthrd = ((TcpClient *)en->Current)->GetStream();
            sub2=S"";
            sub2 = mesg->Substring(5,(index-5));
            String *sndstr = S"";
            sndstr = String::Concat(sndstr,listBox1->Items->get_Item(thrdnos[thrdno]/*thrdno*/)->ToString());
            sndstr = String::Concat(sndstr,S" : ");
            sndstr=String::Concat(sndstr,sub2);
            sndthrd->Write(System::Text::Encoding::ASCII->GetBytes(sndstr),0,sndstr->Length);
       }
       else if(!String::Compare(tmpsub,S"###03")) //Logout request from Client
       {
      IEnumerator *enmrtr = sockList->GetEnumerator();
             NetworkStream *strm;
             while (enmrtr->MoveNext())
             {
                  strm= ((TcpClient *) enmrtr->Current)->GetStream();
                  strm->Write(System::Text::Encoding::ASCII->GetBytes(S"###02"),0,5);
                  Thread::Sleep(500);
                  for(int i=0;i < listBox1->Items->Count;i++)
                  {
                      if(i == thrdnos[thrdno]/*thrdno*/)
                      {
                           //tmpsttr->Finalize();
                           Thread::Sleep(500);
                           continue;
                      }
                      String *tmpsttr=S"";
                      tmpsttr = String::Concat(S"###01",listBox1->Items->get_Item(i)->ToString());
                      strm->Write(System::Text::Encoding::ASCII->GetBytes(tmpsttr),0,tmpsttr->Length);
                      tmpsttr=S""; tmpsttr->Finalize(); Thread::Sleep(500);
                  }
             }
             Items->RemoveAt(thrdnos[thrdno]);
             RemoveAt(thrdnos[thrdno]/*thrdno*/);
             strmList->RemoveAt(thrdnos[thrdno]/*thrdno*/);
             for(int slot= (thrdno+1);slot <= listBox1->Items->Count;slot++)
             {
                    thrdnos[slot] = thrdnos[slot]-1;
             }
             readstream->Write(System::Text::Encoding::ASCII->GetBytes(S"###09"),0,5);
             readstream->Close();
             return;
             //break;
        }
          /////////////////////////////
   }
}

Server maintains the list of all clients like this...

cl = server->AcceptTcpClient(); strm = cl->GetStream(); 
sockList->Add(cl);

At client side, This is the main thread....

 static void readingthrdcl()
  {
    while(1)
    {
    Byte buff[] = new Byte[100];
    int len;
    try {
     len=readingStream->Read(buff,0,buff->Length);
    }
    catch(Exception *e)
            {
      System::Windows::Forms::MessageBox::Show(e->Message);
        }
       String *str;
       str = S"";
       str = System::Text::Encoding::ASCII->GetString(buff,0,len);
       len =  str->Length;
       String *substr;
       substr = System::Text::Encoding::ASCII->GetString(buff,0,5);
       int cur;
          if(!String::Compare(substr,S"###01"))
          {
     String *namestr;
     namestr = System::Text::Encoding::ASCII->GetString(buff,0,len);
     namestr=namestr->Remove(0,5);
     listBox1->Items->Add(namestr);
     nameList->Add(namestr);
     namestr->Finalize();
    }
    else if(!String::Compare(substr,S"###02"))
    {
      listBox1->Items->Clear();
       }
       else if(!String::Compare(substr,S"###09"))
       {
      readingStream->Close();
     //Thread::Abort();
      return;
    }
     richTextBox3->Text = String::Concat(richTextBox3->Text,System::Text::Encoding::ASCII->GetString(buff,0, buff->Length));
     buff->Finalize();
   }

 }

Points of Interest

Here I have used different codes to interprit the type of message like login request, logout request, message sending request. This code's are passed as a header information with each of the message.

Next, when I was writing the application, I was able to create threads, connect to the server, and even synchronize the threads but still I was not able to send message to any person in the login list. Later I found that when you receive a message from the socket in the buffer, it returns the value of number of characters received which I was not storing. So during the time of filling the login list, the generated string of name of loged in person was differing from the name of that person at the server. Because the string was generated from the buffer and as I was not storing the returened value of the read() function of the socket, the generated string's length was just equal to the size of buffer and so differed from the corrosponding string at server and server was not able to pass the sent message to the intended user. 

Comment Request!
Thank you for reading this post. Please post your feedback, question, or comments about this post Here.
Login to add your contents and source code to this article
 [Top] Rate this article
 
 About the author
 
Bhupendra Rana
My qualification is BE - IT and MCAD.NET. I am currently working with Persistent Systems Pvt. Ltd(http://www.persistentsys.com/) on .Net technologies based projects. I have special interest in computer networks and mobile communication technologies.
Looking for C# Consulting?
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models.
Click here to learn more about C# Consulting.
 
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
Nevron Chart for .NET 2010.1 Now Available
The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
ASP.NET 4 Hosting
Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites – Click Here!
 
 Post a Feedback, Comment, or Question about this article
Subject:
Comment:
Team Foundation Server Hosting
Become a Sponsor
 Comments
Not able to configure. by Amit On February 14, 2012
Thanks for your post.But where the start server button which I have to click to start the server?
Reply | Email | Modify 
Team Foundation Server Hosting
 © 2012  contents copyright of their authors. Rest everything copyright Mindcracker. All rights reserved.