Skip to main content

Multithreaded C# TCP server to handle multiple clients

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;}
    }
}
}

Comments

  1. If you wish for to increase your knowledge simply keep visiting this site and be updated with the most up-to-date news
    posted here.

    ReplyDelete

Post a Comment

Share your wisdom

Popular posts from this blog

Decoding JPEG image file using libavcodec

I got a chance to work on a video encoding application that decodes series of jpeg files and convert them into ogg theora video file. I used the infamous libavcodec library that is used in FFMPEG . I decided to write blog posts explaining how I decode jpeg images and convert them into ogg video file. This is the first part and in this I will explain how to decode jpeg images using libavcodec. To learn how to write decoded images as a ogg video file please read http://random-stuff-mine.blogspot.com/2017/07/encoding-raw-images-to-ogg-theora-video.html Before reading this blog post you must be aware of using and setting up libavcodec. I highly recommend this tutorial to get basics of using libavcodec http://www.ffmpeg.org/doxygen/0.6/api-example_8c-source.html Allocating input format context We will first allocate input format for reading the file. We will use avformat_open_input function that will allocate AVFormatContext structure passed to it , the function detects input typ

CryptographicException: An error occurred while trying to encrypt the provided data. Refer to the inner exception for more information

I created a new Blazor Server app in Visual Studio 2019 and tried to run it. But I was getting this error CryptographicException: An error occurred while trying to encrypt the provided data. Refer to the inner exception for more information. I couldn't find any reason or solution to this problem. I tried creating the project multiple times but same error. I created a new .Net Core Web App and added a new razor component and included that component in a razor page (cshtml file) like this @(await Html.RenderComponentAsync<GeofenceWork>(RenderMode.ServerPrerendered)) and <component type="typeof(GeofenceWork)" render-mode="serverprerendered" /> As soon as I navigate to this page that has component added I got the same error: CryptographicException: An error occurred while trying to encrypt the provided data. Refer to the inner exception for more information. This was very frustrating. After hours of trying and searching I figured out the solution.