Click here to Skip to main content
15,885,366 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm still figuring out this low-level network communications thing so bear with me.

In a client-server environment (simple chat app) with multiple clients "connected," is it possible to reuse the same socket to broadcast a message to all the the clients? I put connected in quotes as no client maintains a TCP connection on it's own socket but the server maintains a list of IP Address/port that the client applications are listening on. I am just trying to get the broadcast function to work and will worry about handling disconnected clients later.

Now, when there is only one client connected, this code works just fine. As soon as another client connects, it dies when it tries to loop through.
C#
private void TransmitToAll(byte[] message)
{
 Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

 foreach (ChatConnection conn in _connectedClients)
 {
   // it gets through one loop and dies here on the second attempt.
   soc.Connect(conn.Address, 25001);

   soc.Send(message);

   soc.Disconnect(true);
 }

 soc.Dispose();
}

The error that it gives me is:

Once the socket has been disconnected, you can only reconnect again asynchronously, and only to a different EndPoint. BeginConnect must be called on a thread that won't exit until the operation has been completed.

For this first attempt, I would like to keep with a synchronous broadcast process so using async sockets is not on the table yet (that comes later).

What I have tried:

I have tried to reconfigure this code in multiple ways but it still fails. I know that I could easily just create a new socket for each broadcast but that feels wrong and just plain inefficient. I've tried different socket options such as setting DontLinger to false but that had no effect.
Posted
Comments
Kornfeld Eliyahu Peter 6-Aug-17 9:28am    
To ensure that all data is sent and received before the socket is closed, you should call Shutdown before calling the Disconnect method.

If you need to call Disconnect without first calling Shutdown, you can set the DontLingerSocket option to false and specify a nonzero time-out interval to ensure that data queued for outgoing transmission is sent. Disconnect then blocks until the data is sent or until the specified time-out expires. If you set DontLinger to false and specify a zero time-out interval, Close releases the connection and automatically discards outgoing queued data.

https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.disconnect(v=vs.110).aspx
Foothill 7-Aug-17 11:31am    
I think that my problem is that the server is reconnecting to the same client to send a second message and that is causing this error. Is there any way around that or should I use a small pool of sockets to get around this?

I did manage to get it to work with a create->send->acknowledge->close pattern but if the server ends up with dozens of clients connected, it seems very inefficient to be creating a whole new socket just to send a bit of text to all the clients.
Kornfeld Eliyahu Peter 7-Aug-17 15:00pm    
If I think a second time, your problem is that the server connects the clients, and not just accepts connections...
Foothill 7-Aug-17 16:29pm    
Yea, I am beginning to think that what I am trying to do just isn't possible with TCP/IP. I think it would be better to switch over to UDP so I could use the socket in a fire-and-forget way to broadcast to all the clients.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900