MrDysprosium MrDysprosium - 2 months ago 37
C# Question

How to handle multiple active connections in a TCP C# socket server?

My socket server is pretty simple so far:

public static void listen()
{
TcpListener server = null;
IPAddress address = IPAddress.Parse("127.0.0.1");
try
{
server = TcpListener.Create(5683);
server.Start();

}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
}


while (true)
{
Thread.Sleep(10);
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Accepted Client");

Thread thread = new Thread (new ParameterizedThreadStart(SwordsServer.ClientHandler));
thread.IsBackground = true;
thread.Start(client);
}
}

public static void ClientHandler(object c)
{
TcpClient client = (TcpClient)c;
NetworkStream netstream = client.GetStream();
bool connected = true;
while (connected)
{
Thread.Sleep(10);
try
{
byte[] bytes = new byte[client.ReceiveBufferSize];
netstream.Read(bytes, 0, bytes.Length);
Console.WriteLine("got data");
netstream.Write(bytes, 0, bytes.Length);

}
catch (Exception e)
{
connected = false;
Console.WriteLine(e);
Console.WriteLine(e.StackTrace);
}
}
}


My question is, on a conceptual level, how would you keep tabs on each unique
client
and send updates from other threads to specific clients?

For example, if I have data for a specific client, how do I reach out to that client instead of broadcasting it? Or, if a client is no longer connected, how could I tell?

Thanks in advance for any assistance!

Answer

Your implementation for accepting multiple connections creates anonymous clients, meaning after more than 1 connection you wont be able to identify the right client. If identifying is the problem then you can do one thing, have the client send an identifier to the server like "Client1". Create a Dictionary and in your method ClientHandler(), read the identifier from client and add the TCPClient's object in the dictionary.

So the modified code would be something like this:

 Dictionary<string, TCPClient> dictionary = new Dictionary<string, TCPClient>();


 public static void ClientHandler(object c)
    {
        TcpClient client = (TcpClient)c;
        NetworkStream netstream = client.GetStream();
        bool connected = true;
        while (connected)
        {
            Thread.Sleep(10);
            try
            {
                byte[] bytes = new byte[client.ReceiveBufferSize];

                //read the identifier from client
                netstream.Read(bytes, 0, bytes.Length);

                String id = System.Text.Encoding.UTF8.GetString(bytes);

                //add the entry in the dictionary
                dictionary.Add(id, client);
                Console.WriteLine("got data");
                netstream.Write(bytes, 0, bytes.Length);

            }
            catch (Exception e)
            {
                connected = false;
                Console.WriteLine(e);
                Console.WriteLine(e.StackTrace);
            }
        }
    }

Do note: Your application should be intelligent enough to dynamically decide on to which client the updates should be sent.

Comments