I created a simple persistent socket connection for our game using TcpClient
and NetworkStream
. There's no problem connecting, sending messages, and disconnecting normally (quitting app/server shuts down/etc).
However, I'm having some problems where, in certain cases, the client isn't detecting a disconnection from the server. The easiest way I have of testing this is to pull out the network cable on the wifi box, or set the phone to airplane mode, but it's happened in the middle of a game on what should otherwise be a stable wifi.
Going through the docs for NetworkStream
etc, it says that the only way to detect a disconnection is to try to write to the socket. Fair enough, except, when I try, the write passes as if nothing is wrong. I can write multiple messages like this, and everything seems fine. It's only when I plug the cable back in that it sees that it's disconnected (all messages are buffered?).
The TcpClient
is set to NoDelay
, and there's a Flush()
called after every write anyway.
What I've tried:
NetworkStream
- no joyCanWrite
, Connected
, etc all return trueTcpClient.Client.Poll( 1000, SelectMode.SelectWrite );
- returns trueTcpClient.Client.Poll( 1000, SelectMode.SelectRead ) && TcpClient.Client.Available == 0
- returns trueTcpClient.Client.Receive(buffer, SocketFlags.Peek) == 0
- when connected, blocks for about 10-20s, then returns true. When no server, blocks forever(?)NetworkStream.Write()
- doesn't throw an errorNetworkStream.BeginWrite()
- doesn't throw an error (not even when calling EndWrite()
)WriteTimeout
- had no effectSo am I doing something wrong here? Is there any way to get the NetworkStream
to throw an error (like it should) when writing to a socket that should be disconnected?
I've no problem with a keep-alive (the default case is the server will notify the client that it hasn't received anything in a while, and the client will send a heartbeat), but at the minute, according to the NetworkStream
everything's hunky-dory.
It's for a game, so ideally the detection should be quick enough (as the user can still move through the game until they need to make a server call, some of which will block the UI, so the game seems broken).
I'm using Unity, so it's .Net 2.0
is to pull out the network cable on the wifi box
That's a good test. If you do that the remote party is not notified. How could it possibly find out? It can't.
when I try, the write passes as if nothing is wrong
Writes can (and are) buffered. They eventually enter a block hole... No reply comes back. The only way to detect this is a timeout.
So am I doing something wrong here?
You have tried a lot of things but fundamentally you cannot find out about disconnects if no reply comes back telling you that. Use a timeout.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With