最近工作中涉汲到一些Socket 方面应用 ,如断线重连,连接状态判断等,今天做了一些总结。
1.判断Socket 连接状态
通过 Poll 与 Connected 结合使用 ,重点关注 SelectRead 模式
方法名:
Socket.Poll (int microSeconds, System.Net.Sockets.SelectMode mode) 方法参数:
参数枚举:
SelectRead 如果已调用 Listen(Int32) 并且有挂起的连接,则为 true。 - 或 - 如果有数据可供读取,则为 true。 - 或 - 如果连接已关闭、重置或终止,则返回 true; 否则,返回 false。
SelectWrite 如果正在处理 Connect(EndPoint) 并且连接已成功,则为 true; - 或 - 如果可以发送数据,则返回 true; 否则,返回 false。
SelectError 如果正在处理不阻止的 Connect(EndPoint),并且连接已失败,则为 true; - 或 - 如果 OutOfBandInline 未设置,并且带外数据可用,则为 true; 否则,返回 false。
SelectRead 模式返回 true 的三种情况,若Socket 处挂起状态 ,同时没有数据可读取,可以确定Socket 是关闭或终止的。
1.已调用 Listen(Int32) 并且有挂起的连接,则为 true
2.有数据可供读取,则为 true
3.如果连接已关闭、重置或终止,则返回 true
如下代码 ,true 表示连接断开
s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0) || !s.Connected
稍作调整,判断连接状态完整代码如下:
public static bool IsSocketConnected(Socket s) { #region remarks /* As zendar wrote, it is nice to use the Socket.Poll and Socket.Available, but you need to take into consideration * that the socket might not have been initialized in the first place. * This is the last (I believe) piece of information and it is supplied by the Socket.Connected property. * The revised version of the method would looks something like this: * from:http://stackoverflow.com/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c */ #endregion #region 过程 if (s == null) return false; return !((s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)) || !s.Connected); /* The long, but simpler-to-understand version: bool part1 = s.Poll(1000, SelectMode.SelectRead); bool part2 = (s.Available == 0); if ((part1 && part2 ) || !s.Connected) return false; else return true; */ #endregion }
2. Socket Blocking 属性
默认情况 Blocking 为 true ,即阻塞状态, Read 时 若没收到数据 , Socket 会挂起当前线程,直到收到数据,当前线程才被唤醒。适用于接收到数据完成后再进行下一步操作场景 。 反之Blocking 为 false ,调用 Recevied 后,无论是否收到数据,都立即返回结果,当前线程可以继续执行。
MSDN 强调, Blocking 属性值与异步操作 如 (Begin 开始API) BeginReceive 等没有相关性 , 比如通过 BeginReceive 接收数据,同时希望当前线程挂起,看起来,似乎可将 Blocking设为 true 实现 。其实不然,需要通过信号量 ManualResetEvent 实现挂起操作。
The Blocking property has no effect on asynchronous methods. If you are sending and receiving data asynchronously and want to bloc