views:

541

answers:

5

I'm writing an emulator for a game and one of the functions is "SendToAll". How can I check which sockets are still connected? (The client doesn't send a Logout/Disconnect packet.)

A: 

See http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.connected.aspx

Seems that is does what you need.

MainMa
Will it check if it is still connected or will it give the connection status of the last send/receive?If it just does that, how can I make it check the current status?
lesderid
It checks the status of the last sent/receive(or if any error or close has occured. You can't check the status of a TCP socket without reading/writing to it.
nos
Well, according to the documentation, "The Connected property gets the connection state of the Socket as of the last I/O operation."Maybe you can just send something inside a try/throw block to find if the socket is still connected?
MainMa
A: 

Use Socket.Connected Property.

KMan
Just note that even if Socket.Connected returns true, the socket might not be connected. If it is false, it's definitely not connected though.
nos
A: 

The Socket.Connected property will tell you whether a socket thinks it's connected. It actually reflects the status of the last send/receive operation performed on the socket.

If the socket has been closed by your own actions (disposing the socket, calling methods to disconnect), Socket.Connected will return false. If the socket has been disconnected by other means, the property will return true until you next attempt to send or recieve information, at which point either a SocketException or ObjectDisposedException will be thrown.

You can check the property after the exception has occurred, but it's not reliable before.

Programming Hero
+4  A: 

As Programming Hero answered Socket.Connected cannot be used in this situation. You need to poll connection every time to see if connection is still active. This is code I used:

    bool SocketConnected(Socket s)
    {
        bool part1 = s.Poll(1000, SelectMode.SelectRead);
        bool part2 = (s.Available == 0);
        if (part1 & part2)
            return false;
        else
            return true;
    }

It works like this:

  • s.Poll returns true if
    • connection is closed, reset, terminated or pending (meaning no active connection)
    • connection is active and there is data available for reading
  • s.Available returns number of bytes available for reading
  • if both are true:
    • there is no data available to read so connection is not active
zendar
It is working. Thank you again!
lesderid
A: 

The best way is simply to have your client send a PING every X seconds, and for the server to assume it is disconnected after not having received one for a while.

I encountered the same issue as you when using sockets, and this was the only way I could do it. The socket.connected property was never correct.

In the end though, I switched to using WCF because it was far more reliable than sockets.

SLC