有没有办法仅在有内容可供读取时才在 C# 中轮询套接字?
题
我想知道当只有一个条件(数据可供读取)满足时,是否有一种方法可以在 C# 中轮询套接字,我知道 套接字轮询 方法,但如果指定的 3 个条件中的任意数量返回 true(如此处指定),则可以返回 true: 微软软件定义网络:套接字轮询
解决方案
根据 MSDN 文档,有 3 个原因返回 true:
Poll(microSeconds, SelectMode.SelectRead);
- 如果
Listen()
已被调用并且连接正在挂起 - 如果数据可供读取
- 如果连接已关闭、重置或终止
让我们看看我们是否可以区分它们:
- 你总是知道如果
Listen()
之前已被调用过,因此如果没有调用过,则无需考虑该原因。 - 好吧,你就这么做吧。
- 意味着你不能停留在 Poll() 调用中,需要找出到底发生了什么。一种选择是在之后立即检查套接字的状态
Poll()
回。
结论:
不需要考虑
和 3.可以通过每次返回 true 时检查套接字状态来处理。
所以我会选择(未经测试):
if (s.Poll(microSeconds, SelectMode.SelectRead)))
{
if (!s.Connected)
// Something bad has happened, shut down
else
// There is data waiting to be read"
}
其他提示
您可以使用socket属性可用。它返回多少数据是可读取的。
发现在类的NetworkStream东西。物业 NetworkStream.DataAvailable 返回true如果数据可用于阅读。的NetworkStream的对象返回处理的TcpListener和TcpClient的。这比插座一个更高的抽象层。
我发现没有办法来自套接字到的NetworkStream。甲的NetworkStream是使用插座,并且是插座的流表示。但我不知道是什么的NetworkStream与插座做什么。
您可以在底层上手柄使用选择()系统调用。
可以使用Select()方法,而不是轮询()。 实际上看时成Socket.Poll与内部码被调用套接字上选择ILSpy(反射器工具)。
此外,调用轮询()在紧凑循环中会增加内存分配因为它一个新的IntPtr []在每次调用。 调用select(),您可以重复使用数组来代替引擎盖下分配新的。
真; -要么- 真,如果数据可用于阅读; -要么- 真如果连接已经关闭,复位,或终止; 否则,返回false。
据我所知,你要检查,如果第二个选项是一个返回true?检查是否投票返回true后,您可以检查,如果连接是打开的,这意味着,不连接,关闭,复位或终止。
如果它是开放的,那么它的第二个选项返回true。