Unity3D 中使用 Socket.Poll 方法遇到的小坑

昨天下班之前提交了一个小小的改动,就是把 Socket.Poll(int microSeconds, SelectMode mode) 方法中的 microSeconds 参数改成了-1,原因是我看到了.NET Framework 文档中的这么一句话。

Poll will block execution until the specified time period, measured in microseconds, elapses. Set the microSeconds parameter to a negative integer if you would like to wait indefinitely for a response.

好吧,我承认我不矜持了,我看到这段描述的时候顿时一尿啊,赶紧把我之前设置的 1000 微秒改成了-1,我想这个 1000 微秒还是很有可能会出现没有得到实际的结果的情况啊,所以统统都搞成-1 吧,我就死等你返回结果还不行吗?好吧,改完了,赶紧测试一下,在 Editor 和自己的 iPhone 5S 上分别测试了一下,貌似木有问题,然后就提交了。

晚上回到家,同事就发来消息说是新版本无法进入游戏,卸载重新装了一个中午的包就 OK 了,当时心里头咯噔一下,难道真的是这个改出来的问题。今天早上一到公司,策划同学打开 Editor(Windows 下)正要进游戏发现一直就卡在那儿。跟服务器的同学折腾了一番,WireShark 和 tcpdump 都用上了,最终还是没有找到为啥。好吧,那就试试把昨天改的这点代码一点点恢复,最终发现就是因为这个鬼导致的。

就是这个 SelectMode.SelectError 配合-1 导致的,SelectMode.SelectRead 和 SelectMode.SelectWrite 配合-1 并不会出现这个问题,所以好吧,那就果断先把 SelectError 这货的时间参数修改回来吧。再仔细一看,原来这个时间参数是用微秒作单位的,所以 1000 是不是有点太短了呢?至少也传个 500 毫秒吧,在目前的这种移动网络环境下,这个时间是不是会更合适一些呢?测试一下呗,这回在 Android 和 Windows Editor 上都 OK 了。

记录一下这个坑,使用 Socket.Poll(int microSeconds, SelectMode mode) 这个方法的时候,在 Android 平台和 Windows Editor 平台下会出现因为将 microSeconds 设置为-1 导致程序会 Hang 住在 Poll 方法这儿,这个线程就算是杯具了,这也是我的应用场景下出现所有网络请求都超时,无法收到服务器的返回(实际上服务器每次都成功返回了,而且每次超时之后重试发送的消息也都能发送出去),就是因为我在读取服务器返回的线程中调用了 Poll 方法查询当前这条 Socket 连接是否出错了导致的。


修改完了之后,我又再看了一遍.NET Framework 中关于 Poll 方法的文档,然后看到了这么一段话:

This method cannot detect certain kinds of connection problems, such as a broken network cable, or that the remote host was shut down ungracefully. You must attempt to send or receive data to detect these kinds of errors.

尼玛啊,好吧,那还得想办法来针对这两种非正常断开与服务器连接的情况进行处理,好吧,等着我啊。