Googler

两情相悦,又岂在朝朝暮暮。

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编辑  收藏  举报

导航

Apple/苹果笔记本 Mac Air MC968CH/A 行货在保 I5 11寸 超级本