Multi client - server architecture messaging system using Threads

By Perry
Access over 40 UI widgets with everything from interactive menus to rich charts.

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

Popularity  (2210 Views)