Socket模拟Ping
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Diagnostics; namespace Rocky.Net { public class PingWatch { public static IPEndPoint Parse(string input) { var arr = input.Split(':'); if (arr.Length != 2) { throw new FormatException(string.Format("'{0}' is Invalid.", input)); } return new IPEndPoint(IPAddress.Parse(arr[0]), int.Parse(arr[1])); } private Stopwatch _watcher; private double[] _milliseconds; public int PingTimes { get { return _milliseconds.Length; } set { if (value < 1) { throw new ArgumentOutOfRangeException(string.Format("PingTimes must > 1, Current value is {0}.", value)); } if (_milliseconds == null) { _milliseconds = new double[value]; } else { Array.Resize(ref _milliseconds, value); } } } public int PerSleep { get; set; } public PingWatch(int pingTimes = 4, int perSleep = 200) { _watcher = new Stopwatch(); this.PingTimes = pingTimes; this.PerSleep = perSleep; } public PingResult Ping(string input) { var ep = Parse(input); return Ping(ep); } public PingResult Ping(IPEndPoint ep, int connectTimeout = 3000) { int perSleep = this.PerSleep; bool doSleep = perSleep > 0; for (int i = 0; i < _milliseconds.Length; i++) { var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sock.Blocking = false; try { _watcher.Restart(); sock.Connect(ep); } catch (SocketException ex) { // 10035 == WSAEWOULDBLOCK if (ex.NativeErrorCode != 10035) { throw; } // Wait until connected or timeout. // SelectWrite: returns true, if processing a Connect, and the connection has succeeded. if (sock.Poll((connectTimeout * 1000), SelectMode.SelectWrite)) { _watcher.Stop(); _milliseconds[i] = _watcher.Elapsed.TotalMilliseconds; } else { _milliseconds[i] = 0; } } finally { sock.Dispose(); if (doSleep) { Runtime.Sleep(perSleep); } } } return new PingResult(_milliseconds); } } #region PingResult public struct PingResult { public static bool operator ==(PingResult t1, PingResult t2) { return t1.LosePercentage == t2.LosePercentage && t1.AverageValue == t2.AverageValue; } public static bool operator !=(PingResult t1, PingResult t2) { return t1.LosePercentage != t2.LosePercentage && t1.AverageValue != t2.AverageValue; } public static bool operator >(PingResult t1, PingResult t2) { return t1.LosePercentage > t2.LosePercentage && t1.AverageValue > t2.AverageValue; } public static bool operator >=(PingResult t1, PingResult t2) { return t1.LosePercentage >= t2.LosePercentage && t1.AverageValue >= t2.AverageValue; } public static bool operator <(PingResult t1, PingResult t2) { return t1.LosePercentage < t2.LosePercentage && t1.AverageValue < t2.AverageValue; } public static bool operator <=(PingResult t1, PingResult t2) { return t1.LosePercentage <= t2.LosePercentage && t1.AverageValue <= t2.AverageValue; } public int LosePercentage { get; set; } public double? AverageValue { get; set; } public PingResult(double[] milliseconds) : this() { int loseCount = milliseconds.Where(t => t < 1).Count(); if (loseCount > 0) { this.LosePercentage = (loseCount / milliseconds.Length) * 100; } if (loseCount < milliseconds.Length) { this.AverageValue = milliseconds.Where(t => t > 0).Average(); } } public bool Equals(PingResult obj) { return this == obj; } public override bool Equals(object obj) { if (obj is PingResult) { return this.Equals((PingResult)obj); } return base.Equals(obj); } public override int GetHashCode() { return base.GetHashCode(); } } #endregion }
当然可以考虑直接使用System.Net.NetworkInformation.Ping~
posted on 2012-12-27 18:01 RockyLOMO 阅读(1110) 评论(1) 编辑 收藏 举报