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