TcpClient/NetworkStream not detecting disconnection

不想你离开。 提交于 2019-12-23 10:07:44

问题


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:

  • Writing a message to the NetworkStream - no joy
  • CanWrite, Connected, etc all return true
  • TcpClient.Client.Poll( 1000, SelectMode.SelectWrite ); - returns true
  • TcpClient.Client.Poll( 1000, SelectMode.SelectRead ) && TcpClient.Client.Available == 0 - returns true
  • TcpClient.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 error
  • NetworkStream.BeginWrite() - doesn't throw an error (not even when calling EndWrite())
  • Setting a WriteTimeout - had no effect
  • Having a specific time where we haven't received a message from the server (normally there's a keep-alive) - I had this, but removed it, as we were getting a lot of false-positives due to lag etc (some clients would see between 10-20s of lag)

So 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


回答1:


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.



来源:https://stackoverflow.com/questions/31322716/tcpclient-networkstream-not-detecting-disconnection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!