TcpClient/NetworkStream未检测到断开连接 [英] TcpClient/NetworkStream not detecting disconnection

查看:347
本文介绍了TcpClient/NetworkStream未检测到断开连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用TcpClientNetworkStream为我们的游戏创建了一个简单的持久套接字连接.连接,发送消息和正常断开连接都没有问题(退出应用程序/服务器关闭/等).

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).

但是,在某些情况下,客户端没有检测到与服务器的断开连接,我遇到了一些问题.测试的最简单方法是拔出wifi盒上的网络电缆,或将手机设置为飞行模式,但这是在游戏中发生的,否则应该是稳定的wifi.

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.

浏览NetworkStream等文档时,它说检测到断开连接的唯一方法是尝试写入套接字.相当公平,除了,当我尝试时,写入通过就好像没有什么不对.我可以这样写多条消息,一切似乎都很好.只有当我重新插入电缆时,它才会断开连接(所有消息都已缓冲?).

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?).

TcpClient设置为NoDelay,并且每次写操作后都会调用Flush().

The TcpClient is set to NoDelay, and there's a Flush() called after every write anyway.

我尝试过的事情:

  • NetworkStream上写消息-不高兴
  • CanWriteConnected等均返回true
  • TcpClient.Client.Poll( 1000, SelectMode.SelectWrite );-返回true
  • TcpClient.Client.Poll( 1000, SelectMode.SelectRead ) && TcpClient.Client.Available == 0-返回true
  • TcpClient.Client.Receive(buffer, SocketFlags.Peek) == 0-连接时,阻塞大约10-20s,然后返回true.如果没有服务器,则永远阻止(?)
  • NetworkStream.Write()-不会引发错误
  • NetworkStream.BeginWrite()-不会引发错误(即使在调用EndWrite()时也不例外)
  • 设置WriteTimeout-无效
  • 有一个特定的时间,我们没有收到来自服务器的消息(通常有一个保持活动状态)-我有这个,但是删除了它,因为由于滞后等原因,我们得到了很多错误的肯定结果(一些客户会看到10到20秒之间的延迟)
  • 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?

我对保持活动没有任何问题(默认情况下,服务器将通知客户端一段时间内未收到任何消息,客户端将发送心跳信号),但在几分钟内,到NetworkStream一切都是笨拙的.

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.

它是用于游戏的,因此理想情况下,检测应该足够快(因为用户仍然可以在游戏中移动,直到需要进行服务器调用为止,其中有些会阻塞UI,因此游戏似乎坏了).

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).

我正在使用Unity,所以它是.Net 2.0

I'm using Unity, so it's .Net 2.0

推荐答案

是拔出wifi盒上的网络电缆

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.

这篇关于TcpClient/NetworkStream未检测到断开连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆