Multi client - server architecture messaging system using Threads

This is messaging system which able to generates multiple clients-server combination in same machine or on different machine based on IP address and port provided to each pair of client-server.

Complete C# Program

------------------------

Client Code
-----------

Following namespaces are required:

using System;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Threading;

namespace Client
{
  public Thread tcpThd;
  public byte[] readBuffer;
  public byte[] writeBuffer;
  public Stream stm;
  public Socket socket;
  public TcpClient tcpclnt;
  public string loginName = "";

/// <summary>
  /// The main entry point for the application.
  /// </summary>
  [STAThread]
  static void Main()
  {
     //You can keep here loop to create multiple client based on user's wish
     startServer("IP", "Port", "username");
  }

public void startServer(string ipAddress,int portNumber,string loginName)
  {
   this.loginName = loginName;
   tcpclnt = new TcpClient();
   tcpclnt.Connect(ipAddress.Trim(),portNumber);
   textBoxWindow.AppendText("Connecting to server...");
   stm = tcpclnt.GetStream();
   cmdEnter.Enabled = true;
   writeToServer("Hello "+loginName+" welcome to the chat line!!!"+"\r\n");
   tcpThd = new Thread(new ThreadStart(ReadSocket));
   tcpThd.Start();
  }
  
  public void ReadSocket()
  {
   while(true)
   {
    try
    { readBuffer = new Byte[100];
     stm.Read(readBuffer,0,100);
          
     /* If the text box exceed the maximum lenght, then get
      * remove the top part of the text*/
     if(textBoxWindow.Text.Length > textBoxWindow.MaxLength)
     { textBoxWindow.Select(0,300);
      textBoxWindow.SelectedText = "";
     }
     
     textBoxWindow.AppendText(System.Text.Encoding.ASCII.GetString(readBuffer)+"\r\n"); 
    }
  
    catch (Exception e)
    { break; }
   }
  }
  
  public void writeToServer(string strn)
  { System.Text.ASCIIEncoding encord = new System.Text.ASCIIEncoding();
   writeBuffer = encord.GetBytes(strn);
   if(stm != null) stm.Write(writeBuffer,0,writeBuffer.Length);
  }
}
  
Server Code
-----------
using System;
using System.Collections;
using System.Windows.Forms;
using System.Threading;
using System.Net.Sockets;
using System.IO;

namespace Server
{
 /* This stores data about each client */
 public struct ClientData
 { public Socket structSocket;
  public Thread structThread;
 }
 
 /// <summary>
  /// The main entry point for the application.
  /// </summary>
  [STAThread]
  static void Main()
  { Application.Run(new Form1());}

  
  public void WaitingForClient()
  {
   ClientData CData;
   while(true)
   { /* Accept will block until someone connects */
    CData.structSocket = tcpLsn.AcceptSocket();
    Interlocked.Increment(ref connectId);  
    CData.structThread = new Thread(new ThreadStart(ReadSocket));
     
    lock(this)
    { // it is used to keep connected Sockets and active thread
     dataHolder.Add(connectId, CData);
     upDateDataGrid("Connected > "+connectId+"   "+DateTime.Now.ToLongTimeString());
    }
    CData.structThread.Start();
   }
  }
  
  public void ReadSocket()
  {
   /* realId will be not changed for each thread, but connectId is
    * changed. it can't be used to delete object from Hashtable*/
   long realId = connectId;
   Byte[] receive;
   ClientData cd = (ClientData)dataHolder[realId];
   Socket s = cd.structSocket;
   int ret = 0;

   while (true)
   {
    if(s.Connected)
    { receive = new Byte[100] ;
     try
     { /* Receive will block until data coming ret is 0 or Exception
       *  happen when Socket connection is broken*/
      ret = s.Receive(receive,receive.Length,0);

      if (ret>0)
      { foreach(ClientData clntData in dataHolder.Values)
       { if(clntData.structSocket.Connected)
        clntData.structSocket.Send(receive,ret,SocketFlags.None);
       }
      }
      else {  break;}
     }
     catch (Exception e)
     {
     }
    }
   }
   CloseTheThread(realId);
  }
 
  private void CloseTheThread(long realId)
  {
   try
   { ClientData clientData = (ClientData)dataHolder[realId];
    clientData.structThread.Abort();
   }

   catch(Exception e)
   { lock(this)
    { dataHolder.Remove(realId);
     upDateDataGrid("Disconnected > "+realId+"   "+DateTime.Now.ToLongTimeString());
    }
   }
  }
}

Regards,
Megha

By Perry    Popularity  (2427 Views)