110,533
社区成员
发帖
与我相关
我的任务
分享
sealed class pingInterval : IDisposable
{
private sealed class pinger : IDisposable
{
private readonly pingInterval pingInterval;
private fastCSharp.net.ping ping;
private System.Net.IPEndPoint ip;
public pinger(pingInterval pingInterval)
{
this.pingInterval = pingInterval;
ping = new fastCSharp.net.ping(1000, pingInterval.timeoutMilliseconds, null);
}
internal void Next()
{
fastCSharp.threading.task.TinyTask.Add(next);
}
private void next()
{
for (ip = pingInterval.getIP(); ip != null; ip = pingInterval.getIP()) pingInterval.onCompleted(ip, ping.Ping(ip));
pingInterval.free(this);
}
public void Dispose()
{
fastCSharp.net.ping ping = this.ping;
this.ping = null;
if (ping != null) ping.Dispose();
}
}
private const int maxPingCount = 256;
private readonly System.Net.IPEndPoint[] ips;
private int ipIndex;
private readonly object ipLock = new object();
private readonly int intervalSeconds;
private readonly int timeoutMilliseconds;
private action<System.Net.IPEndPoint, bool> onCompleted;
private pinger[] pings;
private readonly pinger[] freePings;
private readonly pinger[] nextPings;
private int freePingIndex;
private DateTime pingTime;
private readonly System.Timers.Timer timer;
private readonly object pingLock = new object();
public pingInterval(System.Net.IPEndPoint[] ips, int intervalSeconds, int timeoutMilliseconds, action<System.Net.IPEndPoint, bool> onCompleted)
{
this.ips = ips;
this.intervalSeconds = intervalSeconds;
this.timeoutMilliseconds = timeoutMilliseconds;
this.onCompleted = onCompleted;
freePingIndex = (intervalSeconds * 1000) / (timeoutMilliseconds + 1000);
if (freePingIndex <= 1) freePingIndex = ips.Length;
else freePingIndex = ips.Length / freePingIndex + 1;
if (freePingIndex > maxPingCount) freePingIndex = maxPingCount;
pings = new pinger[freePingIndex];
freePings = new pinger[freePingIndex];
nextPings = new pinger[freePingIndex];
for (int index = freePingIndex; index != 0; pings[index] = freePings[index] = new pinger(this)) --index;
timer = new System.Timers.Timer(intervalSeconds * 1000);
timer.AutoReset = false;
timer.Elapsed += next;
pingTime = DateTime.Now;
next(null, null);
}
private void next(object sender, System.Timers.ElapsedEventArgs e)
{
while (wait())
{
Console.WriteLine("Start " + DateTime.Now.toString());
System.Threading.Monitor.Enter(pingLock);
int count = freePingIndex;
try
{
Array.Copy(freePings, nextPings, freePingIndex);
freePingIndex = 0;
}
finally { System.Threading.Monitor.Exit(pingLock); }
while (count != 0) nextPings[--count].Next();
DateTime now = DateTime.Now;
if ((pingTime = pingTime.AddSeconds(this.intervalSeconds)) > now)
{
timer.Interval = (pingTime - now).TotalMilliseconds;
if (pings != null) timer.Start();
break;
}
}
}
private bool wait()
{
System.Threading.Monitor.Enter(ipLock);
try
{
if (pings != null)
{
if (ipIndex != 0) System.Threading.Monitor.Wait(ipLock);
ipIndex = ips.Length;
return true;
}
}
finally { System.Threading.Monitor.Exit(ipLock); }
return false;
}
private System.Net.IPEndPoint getIP()
{
System.Threading.Monitor.Enter(ipLock);
try
{
if (ipIndex != 0)
{
System.Net.IPEndPoint ip = ips[--ipIndex];
if (ipIndex == 0) System.Threading.Monitor.Pulse(ipLock);
return ip;
}
}
finally { System.Threading.Monitor.Exit(ipLock); }
return null;
}
private void free(pinger ping)
{
System.Threading.Monitor.Enter(pingLock);
try
{
freePings[freePingIndex++] = ping;
}
finally { System.Threading.Monitor.Exit(pingLock); }
}
public void Dispose()
{
System.Threading.Monitor.Enter(ipLock);
try
{
if (pings != null)
{
timer.Stop();
timer.Elapsed -= next;
foreach (pinger ping in pings) ping.Dispose();
pings = null;
}
System.Threading.Monitor.Pulse(ipLock);
}
finally { System.Threading.Monitor.Exit(ipLock); }
}
}
static int pingCount;
static int pingErrorCount;
static int loopCount = -1;
static System.Net.IPEndPoint[] ips;
static int ipCount;
static void onPing(System.Net.IPEndPoint ip, bool isPing)
{
if (System.Threading.Interlocked.Decrement(ref ipCount) == -1)
{
System.Threading.Interlocked.Add(ref ipCount, ips.Length);
if (++loopCount != 0) Console.WriteLine(DateTime.Now.toString() + " LOOP[" + loopCount.toString() + "] Count[" + (pingCount / loopCount).toString() + "] ErrorCount[" + pingErrorCount.toString() + "]");
}
if (isPing) ++pingCount;
else ++pingErrorCount;
//Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " " + ip.ToString() + " : " + (reply != null && reply.Status == System.Net.NetworkInformation.IPStatus.Success).ToString());
}
static void Main(string[] args)
{
ips = System.IO.File.ReadAllText(@"d:\ip.txt").Split(',').left(16384).getArray(value => new System.Net.IPEndPoint(System.Net.IPAddress.Parse(value), 0));
using (pingInterval pingInterval = new pingInterval(ips, 2, 2000, onPing))
{
Console.ReadKey();
}
Console.WriteLine("End");
Console.ReadKey();
}
sealed class pingInterval : IDisposable
{
private sealed class pinger : IDisposable
{
private readonly pingInterval pingInterval;
private System.Net.NetworkInformation.Ping ping;
private System.Net.IPAddress ip;
public pinger(pingInterval pingInterval)
{
this.pingInterval = pingInterval;
ping = new System.Net.NetworkInformation.Ping();
ping.PingCompleted += pingCompleted;
}
internal void Next()
{
while (ping != null)
{
if ((ip = pingInterval.getIP()) == null)
{
pingInterval.free(this);
break;
}
else
{
try
{
ping.SendAsync(ip, pingInterval.timeoutMilliseconds, this);
break;
}
catch { pingInterval.onCompleted(ip, false); }
}
}
}
private void pingCompleted(object sender, System.Net.NetworkInformation.PingCompletedEventArgs e)
{
pingInterval.onCompleted(ip, e.Error == null);
Next();
}
public void Dispose()
{
if (ping != null)
{
ping.PingCompleted -= pingCompleted;
ping.Dispose();
ping = null;
}
}
}
private const int maxPingCount = 1 << 15;
private readonly System.Net.IPAddress[] ips;
private int ipIndex;
private readonly object ipLock = new object();
private readonly int intervalSeconds;
private readonly int timeoutMilliseconds;
private action<System.Net.IPAddress, bool> onCompleted;
private pinger[] pings;
private readonly pinger[] freePings;
private readonly pinger[] nextPings;
private int freePingIndex;
private DateTime pingTime;
private readonly System.Timers.Timer timer;
private readonly object pingLock = new object();
public pingInterval(System.Net.IPAddress[] ips, int intervalSeconds, int timeoutMilliseconds, action<System.Net.IPAddress, bool> onCompleted)
{
this.ips = ips;
this.intervalSeconds = intervalSeconds;
this.timeoutMilliseconds = timeoutMilliseconds;
this.onCompleted = onCompleted;
freePingIndex = (intervalSeconds * 1000) / (timeoutMilliseconds + 100);
if (freePingIndex <= 1) freePingIndex = ips.Length;
else freePingIndex = ips.Length / freePingIndex + 1;
if (freePingIndex > maxPingCount) freePingIndex = maxPingCount;
pings = new pinger[freePingIndex];
freePings = new pinger[freePingIndex];
nextPings = new pinger[freePingIndex];
for (int index = freePingIndex; index != 0; pings[index] = freePings[index] = new pinger(this)) --index;
timer = new System.Timers.Timer(intervalSeconds * 1000);
timer.AutoReset = false;
timer.Elapsed += next;
pingTime = DateTime.Now;
next(null, null);
}
private void next(object sender, System.Timers.ElapsedEventArgs e)
{
while (wait())
{
System.Threading.Monitor.Enter(pingLock);
int count = freePingIndex;
try
{
Array.Copy(freePings, nextPings, freePingIndex);
freePingIndex = 0;
}
finally { System.Threading.Monitor.Exit(pingLock); }
while (count != 0) nextPings[--count].Next();
DateTime now = DateTime.Now;
if ((pingTime = pingTime.AddSeconds(this.intervalSeconds)) > now)
{
timer.Interval = (pingTime - now).TotalMilliseconds;
if (pings != null) timer.Start();
break;
}
}
}
private bool wait()
{
System.Threading.Monitor.Enter(ipLock);
try
{
if (pings != null)
{
if (ipIndex != 0) System.Threading.Monitor.Wait(ipLock);
ipIndex = ips.Length;
return true;
}
}
finally { System.Threading.Monitor.Exit(ipLock); }
return false;
}
private System.Net.IPAddress getIP()
{
System.Threading.Monitor.Enter(ipLock);
try
{
if (ipIndex != 0)
{
System.Net.IPAddress ip = ips[--ipIndex];
if (ipIndex == 0) System.Threading.Monitor.Pulse(ipLock);
return ip;
}
}
finally { System.Threading.Monitor.Exit(ipLock); }
return null;
}
private void free(pinger ping)
{
System.Threading.Monitor.Enter(pingLock);
try
{
freePings[freePingIndex++] = ping;
}
finally { System.Threading.Monitor.Exit(pingLock); }
}
public void Dispose()
{
System.Threading.Monitor.Enter(ipLock);
try
{
if (pings != null)
{
timer.Stop();
timer.Elapsed -= next;
foreach (pinger ping in pings) ping.Dispose();
pings = null;
}
System.Threading.Monitor.Pulse(ipLock);
}
finally { System.Threading.Monitor.Exit(ipLock); }
}
}