Beispiel #1
0
        void pinger_PingCompleted(object sender, PingCompletedEventArgs e)
        {
            try
            {
                object[] args    = (object[])e.UserState;
                DateTime time    = (DateTime)args[0];
                long     pingNum = (long)args[1];

                PingGraphControl graph = (PingGraphControl)args[2];
                int       pingTargetId = (int)args[3];           // Do not assume the pingTargets or pingGraphs containers will have this key!
                IPAddress remoteHost   = (IPAddress)args[4];
                Ping      pinger       = (Ping)args[5];
                pinger.PingCompleted -= pinger_PingCompleted;
                PingInstancePool.Recycle(pinger);
                if (e.Cancelled)
                {
                    graph.AddPingLogToSpecificOffset(pingNum, new PingLog(time, 0, IPStatus.Unknown));
                    Interlocked.Increment(ref failedPings);
                    return;
                }
                graph.AddPingLogToSpecificOffset(pingNum, new PingLog(time, (short)e.Reply.RoundtripTime, e.Reply.Status));
                if (e.Reply.Status != IPStatus.Success)
                {
                    Interlocked.Increment(ref failedPings);
                    if (clearedDeadHosts && pingTargets.ContainsKey(pingTargetId))
                    {
                        CreateLogEntry("" + time.ToString(dateFormatString) + ", " + remoteHost.ToString() + ": " + e.Reply.Status.ToString());
                    }
                }
                else
                {
                    if (!clearedDeadHosts)
                    {
                        pingTargetHasAtLeastOneSuccess[pingTargetId] = true;
                    }
                    Interlocked.Increment(ref successfulPings);
                }
            }
            finally
            {
                UpdatePingCounts(Interlocked.Read(ref successfulPings), Interlocked.Read(ref failedPings));
            }
        }
Beispiel #2
0
        private void controllerLoop(object arg)
        {
            currentIPAddress = null;
            object[] args             = (object[])arg;
            string   host             = (string)args[0];
            bool     traceRoute       = (bool)args[1];
            bool     reverseDnsLookup = (bool)args[2];

            foreach (PingGraphControl graph in pingGraphs.Values)
            {
                graph.ClearAll();
                graph.MouseDown  -= panel_Graphs_MouseDown;
                graph.MouseMove  -= panel_Graphs_MouseMove;
                graph.MouseLeave -= panel_Graphs_MouseLeave;
                graph.MouseUp    -= panel_Graphs_MouseUp;
            }
            Interlocked.Exchange(ref successfulPings, 0);
            Interlocked.Exchange(ref failedPings, 0);
            pingGraphs.Clear();
            pingTargets.Clear();
            pingTargetHasAtLeastOneSuccess.Clear();
            clearedDeadHosts = false;
            panel_Graphs.Invoke((Action)(() =>
            {
                panel_Graphs.Controls.Clear();
            }));
            graphSortingCounter = 0;
            IPAddress target = null;

            try
            {
                string[] addresses = host.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                target           = StringToIp(addresses[0]);
                currentIPAddress = target.ToString();
                CreateLogEntry("(" + DateTime.Now.ToString(dateFormatString) + "): Initializing pings to " + host);

                // Multiple addresses
                if (addresses.Length > 1)
                {
                    // Don't clear dead hosts from a predefined list
                    clearedDeadHosts = true;
                    foreach (string address in addresses)
                    {
                        IPAddress ip       = StringToIp(address.Trim());
                        string    hostName = reverseDnsLookup ? GetIpHostname(ip) : "";
                        AddPingTarget(ip, hostName);
                    }
                }
                // Route
                else if (traceRoute)
                {
                    CreateLogEntry("Tracing route ...");
                    foreach (TracertEntry entry in Tracert.Trace(target, 64, 5000, reverseDnsLookup))
                    {
                        CreateLogEntry(entry.ToString());
                        AddPingTarget(entry.Address, entry.Hostname);
                    }
                }
                // Single address
                else
                {
                    AddPingTarget(target, host);
                }

                CreateLogEntry("Now beginning pings");
                DateTime lastPingAt = DateTime.Now.AddSeconds(-60);
                byte[]   buffer     = new byte[0];

                long     numberOfPingLoopIterations = 0;
                DateTime tenPingsAt = DateTime.MinValue;
                while (true)
                {
                    try
                    {
                        if (!clearedDeadHosts && tenPingsAt != DateTime.MinValue && tenPingsAt.AddSeconds(10) < DateTime.Now)
                        {
                            if (pingTargets.Count > 1)
                            {
                                IList <int> pingTargetIds = pingTargets.Keys;
                                foreach (int pingTargetId in pingTargetIds)
                                {
                                    if (!pingTargetHasAtLeastOneSuccess[pingTargetId])
                                    {
                                        // This ping target has not yet had a successful response. Assume it never will, and delete it.
                                        panel_Graphs.Invoke((Action)(() =>
                                        {
                                            pingTargets.Remove(pingTargetId);
                                            panel_Graphs.Controls.Remove(pingGraphs[pingTargetId]);
                                            pingGraphs[pingTargetId].MouseDown -= panel_Graphs_MouseDown;
                                            pingGraphs[pingTargetId].MouseMove -= panel_Graphs_MouseMove;
                                            pingGraphs[pingTargetId].MouseLeave -= panel_Graphs_MouseLeave;
                                            pingGraphs[pingTargetId].MouseUp -= panel_Graphs_MouseUp;
                                            pingGraphs.Remove(pingTargetId);
                                            if (pingGraphs.Count == 0)
                                            {
                                                Label lblNoGraphsRemain = new Label();
                                                lblNoGraphsRemain.Text = "All graphs were removed because" + Environment.NewLine + "none of the hosts responded to pings.";
                                                panel_Graphs.Controls.Add(lblNoGraphsRemain);
                                            }
                                            else
                                            {
                                                pingGraphs[pingGraphs.Count - 1].ShowTimestamps = true;                                                 // In case the graph we just removed was the last graph, which is supposed to show the timestamps along its bottom, this will make sure the new (or old) bottom is showing timestamps.
                                            }
                                        }));
                                    }
                                }
                                panel_Graphs.Invoke((Action)(() =>
                                {
                                    panel_Graphs_Resize(null, null);
                                }));
                            }
                            clearedDeadHosts = true;
                        }
                        while (pingDelay <= 0)
                        {
                            Thread.Sleep(100);
                        }
                        int msToWait = (int)(lastPingAt.AddMilliseconds(pingDelay) - DateTime.Now).TotalMilliseconds;
                        while (msToWait > 0)
                        {
                            Thread.Sleep(Math.Min(msToWait, 1000));
                            msToWait = (int)(lastPingAt.AddMilliseconds(pingDelay) - DateTime.Now).TotalMilliseconds;
                        }
                        lastPingAt = DateTime.Now;
                        // We can't re-use the same Ping instance because it is only capable of one ping at a time.
                        foreach (var targetMapping in pingTargets)
                        {
                            PingGraphControl graph  = pingGraphs[targetMapping.Key];
                            long             offset = graph.ClearNextOffset();
                            Ping             pinger = PingInstancePool.Get();
                            pinger.PingCompleted += pinger_PingCompleted;
                            pinger.SendAsync(targetMapping.Value, 5000, buffer, new object[] { lastPingAt, offset, graph, targetMapping.Key, targetMapping.Value, pinger });
                        }
                    }
                    catch (ThreadAbortException ex)
                    {
                        throw ex;
                    }
                    catch (Exception)
                    {
                    }
                    numberOfPingLoopIterations++;
                    if (numberOfPingLoopIterations == 10)
                    {
                        tenPingsAt = DateTime.Now;
                    }
                }
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                if (!(ex.InnerException is ThreadAbortException))
                {
                    MessageBox.Show(ex.ToString());
                }
            }
            finally
            {
                CreateLogEntry("(" + DateTime.Now.ToString(dateFormatString) + "): Shutting down pings to " + host);
                if (isRunning)
                {
                    btnStart_Click(btnStart, new EventArgs());
                }
            }
        }