I decided to write a minimal multithreaded TCP based server as a blog post. Following class can serve as a skeleton for any small or large scale multithreaded TCP socket server. It do not contain much error handling , it is only to give an idea that how multithreaded server works and how it can process multiple clients using threading.
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections.Generic;
namespace RandomStuffMine
{
public class MTServer
{
public int Port{get;set;}
public Socket ServerSocket{get;set;}
private List<Client> Clients=new List<Client>();
private bool runServer=true;
public MTServer(int port)
{
Port=port;
ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public void Start()
{
Thread thr=new Thread(new ThreadStart(StartServer));
thr.IsBackground=true;
thr.Start();
}
public void Stop()
{
runServer=false;
ServerSocket.Close();
while(Clients.Count>0)
{
Clients[0].KeepProcessing=false;
Clients[0].Socket.Close();
Clients.RemoveAt(0);
}
}
private BindSocketAndListen()
{
ServerSocket.Bind(new IPEndPoint(IPAddress.Any, Port));
ServerSocket.Listen(100);
}
private void StartServer()
{
BindSocketAndListen();
while(true)
{
Socket clientSocket=ServerSocket.Accept();
Client cl=new Client();
cl.KeepProcessing=true;
cl.Socket=clientSocket;
Clients.Add(cl); //add to clients collection
ParameterizedThreadStart pts=new ParameterizedThreadStart(ProcessClientThreadProc);
Thread thr=new Thread(pts);
thr.IsBackground=true;
thr.Start(cl); //start client processing thread
clientSocket=null;
cl=null;
}
}
private void ProcessClientThreadProc(object obj)
{
Client clnt=(Client)obj;
Socket clientSocket=clnt.Socket;
byte[] buff=new byte[1024]; //buffer to receive data from client socket
int bread=0;
while(clientSocket.KeepProcessing)
{
try
{
//receive data from client
bread=clientSocket.Receive(buff,0,1024,SocketFlags.None);
}
catch(Exception ex)
{
if (!clnt.KeepProcessing)
return; //we will return as it means socket will be closed by server thread
//else do something with exception
}
if(bread==0)
{
break;
}
//send dummy data
clientSocket.Send(Encoding.ASCII.GetBytes("Hello world"));
}
clientSocket.Close();
Clients.Remove(clnt);
}
//This class represents a client connected to server
public class Client
{
public bool KeepProcessing{get;set;}
public Socket Socket{get;set;}
}
}
}
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections.Generic;
namespace RandomStuffMine
{
public class MTServer
{
public int Port{get;set;}
public Socket ServerSocket{get;set;}
private List<Client> Clients=new List<Client>();
private bool runServer=true;
public MTServer(int port)
{
Port=port;
ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public void Start()
{
Thread thr=new Thread(new ThreadStart(StartServer));
thr.IsBackground=true;
thr.Start();
}
public void Stop()
{
runServer=false;
ServerSocket.Close();
while(Clients.Count>0)
{
Clients[0].KeepProcessing=false;
Clients[0].Socket.Close();
Clients.RemoveAt(0);
}
}
private BindSocketAndListen()
{
ServerSocket.Bind(new IPEndPoint(IPAddress.Any, Port));
ServerSocket.Listen(100);
}
private void StartServer()
{
BindSocketAndListen();
while(true)
{
Socket clientSocket=ServerSocket.Accept();
Client cl=new Client();
cl.KeepProcessing=true;
cl.Socket=clientSocket;
Clients.Add(cl); //add to clients collection
ParameterizedThreadStart pts=new ParameterizedThreadStart(ProcessClientThreadProc);
Thread thr=new Thread(pts);
thr.IsBackground=true;
thr.Start(cl); //start client processing thread
clientSocket=null;
cl=null;
}
}
private void ProcessClientThreadProc(object obj)
{
Client clnt=(Client)obj;
Socket clientSocket=clnt.Socket;
byte[] buff=new byte[1024]; //buffer to receive data from client socket
int bread=0;
while(clientSocket.KeepProcessing)
{
try
{
//receive data from client
bread=clientSocket.Receive(buff,0,1024,SocketFlags.None);
}
catch(Exception ex)
{
if (!clnt.KeepProcessing)
return; //we will return as it means socket will be closed by server thread
//else do something with exception
}
if(bread==0)
{
break;
}
//send dummy data
clientSocket.Send(Encoding.ASCII.GetBytes("Hello world"));
}
clientSocket.Close();
Clients.Remove(clnt);
}
//This class represents a client connected to server
public class Client
{
public bool KeepProcessing{get;set;}
public Socket Socket{get;set;}
}
}
}
If you wish for to increase your knowledge simply keep visiting this site and be updated with the most up-to-date news
ReplyDeleteposted here.