【发布时间】:2015-07-13 00:23:22
【问题描述】:
我使用TcpClient 和NetworkStream 为我们的游戏创建了一个简单的持久套接字连接。正常连接、发送消息和断开连接没有问题(退出应用/服务器关闭/等)。
但是,我遇到了一些问题,在某些情况下,客户端没有检测到与服务器的断开连接。我最简单的测试方法是拔掉 wifi 盒子上的网线,或者将手机设置为飞行模式,但它发生在游戏中间,本来应该是稳定的 wifi。
浏览NetworkStream 等的文档,它说检测断开连接的唯一方法是尝试写入套接字。很公平,除了,当我尝试时,写入通过了,好像没有任何问题。我可以像这样写多条消息,一切似乎都很好。只有当我重新插入电缆时,它才会看到它已断开连接(所有消息都被缓冲了?)。
TcpClient 设置为 NoDelay,并且在每次写入之后都会调用 Flush()。
我尝试过的:
- 给
NetworkStream写消息 - 不开心 -
CanWrite、Connected等都返回true -
TcpClient.Client.Poll( 1000, SelectMode.SelectWrite );- 返回真 -
TcpClient.Client.Poll( 1000, SelectMode.SelectRead ) && TcpClient.Client.Available == 0- 返回真 -
TcpClient.Client.Receive(buffer, SocketFlags.Peek) == 0- 连接后,阻塞大约 10-20 秒,然后返回 true。当没有服务器时,永远阻塞(?) -
NetworkStream.Write()- 不会抛出错误 -
NetworkStream.BeginWrite()- 不会抛出错误(即使在调用EndWrite()时也不会) - 设置
WriteTimeout- 无效 - 有一个特定的时间我们没有收到来自服务器的消息(通常有一个保持活动状态) - 我有这个,但删除了它,因为由于滞后等原因我们得到了很多误报(有些客户会看到 10-20 秒的延迟)
那么我在这里做错了吗?在写入应该断开的套接字时,有什么方法可以让NetworkStream 抛出错误(应该如此)?
我对keep-alive没有问题(默认情况是服务器会通知客户端它有一段时间没有收到任何东西,客户端会发送心跳),但在这一分钟,根据到NetworkStream 一切都很好。
这是针对游戏的,所以理想情况下检测应该足够快(因为用户仍然可以在游戏中移动,直到他们需要进行服务器调用,其中一些会阻塞 UI,所以游戏似乎坏了)。
我使用的是 Unity,所以它是 .Net 2.0
【问题讨论】:
标签: tcp unity3d tcpclient networkstream