zoukankan      html  css  js  c++  java
  • 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~

  • 相关阅读:
    调查:秋色园QBlog 博客开源不开源,您的建议是?
    CYQ.Data 数据框架 V2.0 版本 开放源码 继续开源之路
    CYQ.Data 数据框架 V3.0 版本 开放源码下载有[CYQ.Blog(秋色园QBlog) 完全开放所有源码]
    秋色园QBlog技术原理解析:性能优化篇:用户和文章计数器方案(十七)
    【视频】配置信息管理 的 使用方法(六):实现添加、修改、查询
    【视频】配置信息管理 的 使用方法(五):配置程序之列表、分页控件、按钮
    自然框架的声明
    【自然框架】稳定版的Demo——看点二:权限,权限过滤与验证。
    见到了“公司”定义一个Company类,那么见到了“字段”是不是也可定义一个Column类?
    《锋利的jquery》实例源码下载
  • 原文地址:https://www.cnblogs.com/Googler/p/2836151.html
Copyright © 2011-2022 走看看