public static PingResult PingIt(this IPAddress addr, string name) { PingResult result = new PingResult() { Address = addr, Name = name }; ILog log = LogManager.GetLogger(typeof(PingExtensions)); try { if (string.IsNullOrEmpty(name)) { log.DebugFormat("Pinging {0}", addr.ToString()); } else { log.DebugFormat("Pinging {0} ({1})", addr.ToString(), name); } long ms = 0; uint count = 0; long repeat = 5; int timeout = 1000; // milliseconds //Stopwatch watch = Stopwatch.StartNew(); using (Ping pinger = new Ping()) { for (int i = 0; i < repeat; ++i) { PingReply reply = pinger.Send(addr, timeout); if (reply.Status == IPStatus.Success) { ++count; ms += reply.RoundtripTime; log.DebugFormat("Ping {0} success in {1} ms", addr.ToString(), reply.RoundtripTime); } else { ms += timeout; log.DebugFormat("Ping {0} failure {1}", addr.ToString(), reply.Status.ToString()); } } } //Trace.WriteLine(string.Format("Pinging {0} took {1} ms", addr.ToString(), watch.ElapsedMilliseconds)); log.DebugFormat("Ping {0}, count {1}, total ms {2}", addr.ToString(), count, ms); // If we average more than half, consider it good result.IsPingable = ((double)count / (double)repeat) >= 0.5f; result.AvgTime = ms / repeat; } catch (Exception e) { log.ErrorFormat("Error in PingIt: {0}", addr.ToString()); log.Error(e); } return(result); }
public override CollectedData OnAcquire() { // Find the IP addresses to ping. This will typically provide the IP addresses // of the devices being monitored, and can also provide a subnet to ping, and // also any extra addresses to ping. IPAddressRequest request = new IPAddressRequest("PingCollector"); RequestBus.Instance.MakeRequest(request); if (request.IsHandled == false) { return(null); } ListData <PingResult> d = new ListData <PingResult>(Context); List <Tuple <IPAddress, string> > to_ping = new List <Tuple <IPAddress, string> >(); Dictionary <string, string> ip_to_name_map = new Dictionary <string, string>(); request.IPAddresses.ForEach(i => ip_to_name_map[i.Item1] = i.Item2); // See if a full subnet ping was requested foreach (string s in request.Subnets) { if (IPAddress.TryParse(s, out IPAddress subnet)) { byte[] ping_addr = subnet.GetAddressBytes(); // Collect all the pingable IP addresses on the specified subnet. // 0 and 255 are reserved, so no need to ping them. for (byte i = 1; i < 255; ++i) { ping_addr[3] = i; IPAddress addr = new IPAddress(ping_addr); // Get the name of the device, if we happen to know it string name = string.Empty; ip_to_name_map.TryGetValue(addr.ToString(), out name); to_ping.Add(Tuple.Create(addr, name)); } } } // Now put in the other ip addresses that are being monitored. // Add them to the list of IPs to ping. foreach (Tuple <string, string> ip in request.IPAddresses) { try { if (IPAddress.TryParse(ip.Item1, out IPAddress addr)) { to_ping.Add(Tuple.Create(addr, ip.Item2)); } } catch (Exception) { } } // Remove any duplictes IP addresses that might have gotten in there IPAddressComparer c = new IPAddressComparer(); to_ping.Sort((a, b) => c.Compare(a.Item1, b.Item1)); to_ping = to_ping.Distinct().ToList(); // Create some # of threads for concurrent pinging. The number of threads // will be around request.NumPingers. ManualResetEvent reset_event = new ManualResetEvent(false); int thread_count = 0; List <Thread> threads = new List <Thread>(); List <List <Tuple <IPAddress, string> > > chunks = to_ping.ChunkBy(to_ping.Count / request.NumPingers); foreach (List <Tuple <IPAddress, string> > addrs in chunks) { Thread t = new Thread( () => { Stopwatch watch = Stopwatch.StartNew(); List <Tuple <IPAddress, string> > local_addrs = addrs; foreach (Tuple <IPAddress, string> addr in local_addrs) { PingResult result = addr.Item1.PingIt(addr.Item2); lock (d.Data) d.Data.Add(result); } Trace.WriteLine(string.Format("Pinging {0} addrs took {1} ms", local_addrs.Count, watch.ElapsedMilliseconds)); if (Interlocked.Decrement(ref thread_count) <= 0) { reset_event.Set(); } }); threads.Add(t); } if (threads.Count > 0) { try { thread_count = threads.Count; threads.ForEach(t => t.Start()); reset_event.WaitOne(); } catch (Exception) { } finally { } Dictionary <string, string> ip_to_mac = GetIPAddrsAndMacAddresses(); foreach (PingResult pr in d.Data) { string ip = pr.Address.ToString(); if (ip_to_mac.TryGetValue(ip, out string mac)) { pr.MAC = mac; } } } d.Data.Sort((a, b) => c.Compare(a.Address, b.Address)); return(new CollectedData(Context, true, d)); }