我使用TcpClient
和NetworkStream
为我们的游戏创建了一个简单的持久套接字连接。连接,发送消息和正常断开连接没有问题(退出app / server关闭/等)。
但是,我遇到了一些问题,在某些情况下,客户端没有检测到与服务器断开连接。我测试这个的最简单的方法是拔出wifi盒上的网线,或者将手机设置为飞行模式,但是在游戏过程中发生的事情应该是稳定的wifi。
通过NetworkStream
等文档,它说检测断开连接的唯一方法是尝试写入套接字。很公平,除了,当我尝试时,写入通过似乎没有错。我可以写这样的多条消息,一切似乎都很好。只有当我将电缆插回时才发现它已断开连接(所有消息都被缓冲了?)。
TcpClient
设置为NoDelay
,并且每次写入后都会调用Flush()
。
我尝试了什么:
NetworkStream
写一条消息 - 没有快乐CanWrite
,Connected
等都返回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-20秒,然后返回true。没有服务器时,永远阻止(?)NetworkStream.Write()
- 不会抛出错误NetworkStream.BeginWrite()
- 不会抛出错误(即使在调用EndWrite()
时也没有)WriteTimeout
- 无效我在这里做错了吗?在写入应该断开连接的套接字时,有没有办法让NetworkStream
抛出错误(就像它应该)?
我对保持活动没有任何问题(默认情况是服务器会通知客户端它暂时没有收到任何内容,而客户端会发送心跳),但是在某一刻,根据到NetworkStream
一切都是笨拙的。
这是一个游戏,所以理想情况下检测应该足够快(因为用户仍然可以在游戏中移动,直到他们需要进行服务器调用,其中一些将阻止UI,因此游戏似乎被打破)。
我正在使用Unity,所以它是.Net 2.0
答案 0 :(得分:3)
是拔出wifi盒上的网线
这是一个很好的考验。如果这样做,则不会通知远程方。怎么可能发现?它不能。
当我尝试时,写入传递就好像没有错误
写入可以(并且是)缓冲。他们最终进入了一个封锁洞......没有回复。检测到这种情况的唯一方法是超时。
我在这里做错了吗?
你已经尝试了很多东西,但从根本上说,如果没有回复告诉你,你就无法找到断线。使用超时。