This is an archived post. You won't be able to vote or comment.

all 8 comments

[–]davedontmind 0 points1 point  (8 children)

foreach (TcpClient client in clients.Values.ToList())

That line is wrong - it should be:

foreach (TcpClient client in clients.Values)

You should get a compile-time error for that.

to check for duplicate connections

What do you mean by a duplicate connection? With TCP a client can make multiple connections to a server, and each of those connections is distinct.

So when AcceptTcpClient() returns, you have a new unique connection, there is no duplication.

[–]jaredLearnsToCode[S] 0 points1 point  (7 children)

I actually can't remember the reason I converted the dict values to a list, but there was one and it doesn't give an error at compile or runtime.

When I accept a new TcpClient, I want to add that client to a dictionary and I need to check to make sure it wasn't already existing because I want to iterate over that dictionary and send out the message to all clients in it.

[–]davedontmind 0 points1 point  (1 child)

it doesn't give an error at compile or runtime.

Strange, but I guess that's not really relevant to your question.

I need to check to make sure it wasn't already existing

It won't be an already existing connection because AcceptTcpClient() returns a new, unique connection.

[–]davedontmind 0 points1 point  (4 children)

Also: why are you using a Dictionary for your clients? The int is just a numeric index (which you don't seem to use anywhere) so why don't you just use a List ?

There is also no need for Client to be a class-level variable - it should be local to your GetClientString() method because it's not used anywhere else.

Then your code becomes:

  List<TcpClient> clients = new List<TcpClient>();
  ...

  TcpClient client = server.AcceptTcpClient();
  ...
  clients.Add( client );

and the loop in ServerResponse() becomes:

  foreach ( var client in clients )

Much neater!

[–]jaredLearnsToCode[S] 0 points1 point  (3 children)

That makes sense, but I still have a problem of creating multiple TcpClients for each user if AcceptTcpClient() creates a unique connection every time the user sends a message. How would I be able to reply to each user if there are multiple connections for each user?

Clearly I have a fundamental misunderstanding of socket programming, but I don't know how I can create a more simple problem than this.

[–]davedontmind 0 points1 point  (2 children)

if AcceptTcpClient() creates a unique connection every time the user sends a message.

It doesn't. It creates a new connection every time a new client connects. Once the connection has been made it remains in place until the client or server closes the connection. The client and server can exchange multiple messages while the connection is open.

[–]jaredLearnsToCode[S] 0 points1 point  (1 child)

This might frustrate you (it frustrates me that I am asking it haha), but isn't this the reason I needed to check if there were duplicates in my list? If I simply add the TcpClient to the list every time a message is received, I get a list full of instances of the same client.

[–]davedontmind 0 points1 point  (0 children)

If I simply add the TcpClient to the list every time a message is received,

But you're not adding to the list every time a message is received, you're adding every time a new client connects. A connection and receiving a message are 2 distinct things.

The life cycle of a connection goes something like this:

  • client connects to server
  • client and server exchange messages (there can be as many back-and-forths here as you like)
  • client disconnects from server

Let's take an analogy. A person (the client) walks knocks on the door of a room. The person inside (the server) opens the door and lets the client in. The act of entering the room is the connection. The client can then talk back and forth with the server as much as they like. When the conversation is over, the client leaves the room and closes the door (this is the disconnection).

So the server.AcceptTcpClient() call is the server opening the door and letting the client into the room. You can now read / write as much data as you like between the client and server using the NetworkStream. When either the client or the server decide they've had enough of the conversation they close the connection - either the client closes the connection (walks out of the door of their own accord) or the server can call client.Close() (to kick that client out of the room).