For most common usage patterns keeping a List
of connected clients will be enough. The main point of interest will be deciding: a list of what?
For many applications pure TCP functionality is not convenient to use, so you would need a layer on top of it that transforms the stream into something more like a message queue from which whole self-contained "messages" can be pulled; the format of those messages is dependent on your application.
I dug up an older project of mine that is a client-server configuration where multiple clients connect to the server and offer remote control functionality. In that project the server keeps a List<ConnectedClient>
where:
// This is the whole actual class
private class ConnectedClient
{
public TcpMessageConnection Connection { get; private set; }
public bool ConnectedEventRaised { get; set; }
public ConnectedClient(TcpMessageConnection connection)
{
this.Connection = connection;
}
}
And TcpMessageConnection
looks like:
// Only class outline shown
public class TcpMessageConnection
{
private readonly MessageStream messageStream; // another custom class
private readonly TcpClient tcpClient;
public EndPoint RemoteEndPoint { get; private set; } // who connected here?
public MessageReader MessageReader { get; } // messageStream.Reader
public MessageWriter MessageWriter { get; } // messageStream.Writer
public bool IsCurrentlyDisconnecting { get; private set; }
public void Close();
}
Together with MessageReader
and MessageWriter
(which do the real heavy lifting) this is enough to implement an async-based server that services multiple clients on a single thread.