0

I am currently learning and working on a Client/Server, and I am having some difficult on how I should store the connections.

Here is some sample code:

while (_isRunning)
{
    if (!tcpListener.Pending())
    {
        Thread.Sleep(200);
        continue;
    }

    TcpClient client = tcpListener.AcceptTcpClient();
    // TODO: handle connection
}

I know I will have a handler that will receive/send data to that given client however, just having the handler would not allow me to do things like knowing how many clients are connected, sending a broadcast message or a shutdown message to all.

Would storing client on a list be fine or should I store anything else ?

What would be the correct way to store the clients connected in this case ?

Guapo
  • 3,446
  • 9
  • 36
  • 63
  • A `Dictionary` or `List` might be of use here. `List` should be sufficient. – Matthew Sep 27 '12 at 17:55
  • @Matthew yes but what I meant is, will just a list be sufficient ? Should I keep any other information aside from the TcpClient in order to make my connected clients list ? I am just looking for some reference of what would be a good useful way on how to do it – Guapo Sep 27 '12 at 17:56
  • That would depend on what information you are interested in. If all you care about is the # of connections and being able to broadcast a message, then a plain list of TcpClient would be enough. – Matthew Sep 27 '12 at 17:58

2 Answers2

1

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.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • that's pretty interesting, is that project open source ? I would love to check more into it. I like how it tied up the connected users, it easy to retrieve some useful data like the IP, and I assume your close is to send a close or close that client ? – Guapo Sep 29 '12 at 22:29
  • @Guapo: Not open source, sorry. `Close` simply closes the `MessageStream` (which in turn closes the `TcpClient`'s `Stream`) and the `TcpClient` itself. `IsCurrentlyDisconnecting` is set to `true` before that and used as a guard so the rest of the app does not have to worry about spamming close and causing some kind of error. – Jon Oct 03 '12 at 08:24
0

With a server you are typically not so much interested in the socket as you are in what the socket is for. The approach that I would take would be to have a class that manages the server end of the conversation between the client and the server. This class would be based on a thread so the idea is that each time a connection is accepted, you spin off a thread to handle the conversation and in that thread is a socket for the server end of the connection.

At this point you would be managing the various threads rather than individual sockets. This is a higher level of abstraction and more useful.

How you manage the threads would depend on what you want to do. It may be that you really do not want to worry about it. As each thread does its own thing, when it is done, it just closes its end of the TCP connection and exits.

However until it does exit, the thread class handles the server side of the conversation.

I suggest you check this stackoverflow, Best way to accept multiple tcp clients.

Community
  • 1
  • 1
Richard Chambers
  • 16,643
  • 4
  • 81
  • 106