How to tell when a Socket has been disconnected

后端 未结 5 1307
滥情空心
滥情空心 2021-02-05 11:36

On the client side I need to know when/if my socket connection has been broken. However the Socket.Connected property always returns true, even after the server side has been d

相关标签:
5条回答
  • 2021-02-05 11:42

    After doing some testing, it appears that the documentation for Socket.Connected is wrong, or at least misleading. clientSocket.Connected will only become false after clientSocket.close() is called. I think this is a throwback to the original C Berkeley sockets API and its terminology. A socket is bound when it has a local address associated with it, and a socket is connected when it has a remote address associated with it. Even though the remote side has closed the connection, the local socket still has the association and so it is still "connected".

    However, here is a method that does work:

    !(socket.Poll(0, SelectMode.SelectRead) && socket.Available == 0)
    

    It relies on that fact that a closed connection will be marked as readable even though no data is available.

    If you want to detect conditions such as broken network cables or computers abruptly being turned off, the situation is a bit more complex. Under those conditions, your computer never receives a packet indicating that the socket has closed. It needs to detect that the remote side has vanished by sending packets and noticing that no response comes back. You can do this at the application level as part of your protocol, or you can use the TCP KeepAlive option. Using TCP Keep Alive from .NET isn't particularly easy; you're probably better off building a keep-alive mechanism into your protocol (alternately, you could ask a separate question for "How do I enable TCP Keep Alive in .NET and set the keep alive interval?").

    0 讨论(0)
  • 2021-02-05 11:45

    Maybe solution is to send some dummy data through it and check if it times out?

    0 讨论(0)
  • 2021-02-05 11:49

    I recommend stripping out the higher-level language stuff and explore what happens at the lower-level IO.

    The lowest I've explored was while writing isectd (find on sourceforge). Using the select() system call, a descriptor for a closed socket becomes read-ready, and when isectd would attempt the recv() the socket's disconnected state can be confirmed.

    As a solution, I recommend not writing your own socket IO and use someone else's middleware. There are lots of good candidates out there. Don't forget to consider simple queuing services as well.

    PS. I would have provided URLs to all the above but my reputation (1) doesn't allow it.

    0 讨论(0)
  • 2021-02-05 11:55

    does the clientSocket.Send() method wait for the packet to either be ack/nack'd?

    If not your code is flying onto the next line while socket is still trying to figure out what is going on.

    0 讨论(0)
  • 2021-02-05 11:58

    Just write to your socket as normal. You'll know when it's disconnected by the Exception that says your data couldn't be delivered.

    If you don't have anything to write...then who cares if it's disconnected? It may be disconnected now, but come back before you need it - why bother tearing it down, and then looping a reconnect until the link is repaired...especially when you didn't have anything to say anyway?

    If it bothers you, implement a keep alive in your protocol. Then you'll have something to say every 30 seconds or so.

    0 讨论(0)
提交回复
热议问题