-3

I did a small program that ping my entire network, but I think I have a problem because some equipment stop working (it runs every 2 minutes and takes 1 minute to complete the operation), the question is: ¿Is there a better way to do this?

Here the code:

Console.WriteLine("Haciendo ping a los equipos, no cierre esta ventana... ");
Ping ping = new Ping();
byte[] buffer = new byte[32];
PingOptions pingoptns = new PingOptions(128, true);
int timeout = Convert.ToInt32(ConfigurationManager.AppSettings["timeout"].ToString());
List<Equipo> list_Eq = new List<Equipo>();
DataTable dt = DB.ShowData("select ip from testping where estatus = 1");

// Por cada IP se realiza ping y se  agrega a la lista del modelo
foreach (DataRow item in dt.Rows)
{

    if (ping.Send(item[0].ToString(), timeout, buffer, pingoptns).Status == IPStatus.Success)
    {
        list_Eq.Add(new Equipo
        {
            ip = item[0].ToString(),
            estado = 1
        });
    }
    else
    {
        list_Eq.Add(new Equipo
        {
            ip = item[0].ToString(),
            estado = 0
        });
    }
}

// Se actualiza el estado de las ip segun la respuesta del ping
foreach (var eq in list_Eq)
{
    DB.ExecQuery("update testping set estado = " + eq.estado + " where ip = '" + eq.ip + "'");
}

Thanks

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
U. Angel
  • 3
  • 3

2 Answers2

0

Try Async Ping :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("IP", typeof(string));
            dt.Columns.Add("TimeOut", typeof(int));
            dt.Columns.Add("Canceled", typeof(bool));
            dt.Columns.Add("Error", typeof(List<string>));
            dt.Columns.Add("Reply", typeof(List<PingReply>));
            dt.Columns.Add("Sent", typeof(int));
            dt.Columns.Add("Received", typeof(int));

            dt.Rows.Add(new object[] { "172.160.1.19", 0, false, null, null, 4, 0 });
            dt.Rows.Add(new object[] { "172.160.1.27", 0, false, null, null, 4, 0 });
            dt.Rows.Add(new object[] { "172.160.1.37", 0, false, null, null, 4, 0 });
            dt.Rows.Add(new object[] { "172.160.1.57", 0, false, null, null, 4, 0 });


            MyPing ping = new MyPing(dt); 
        }
    }

    public class MyPing
    {
        static AutoResetEvent waiter = new AutoResetEvent(false);
        const string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        private Object thisLock = new Object();

        DataTable dt;
        Dictionary<string, DataRow> pingDict = new Dictionary<string, DataRow>();
        const int TIMEOUT = 12000;
        public MyPing() { }
        public MyPing(DataTable dtin)
        {
            dt = dtin;

            Console.WriteLine("Haciendo ping a los equipos, no cierre esta ventana... ");



            // Por cada IP se realiza ping y se  agrega a la lista del modelo
            foreach (DataRow item in dt.Rows)
            {
                Ping ping = new Ping();
                string ip = item.Field<string>("IP");
                pingDict.Add(ip, item);
                ping.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);
                byte[] buffer = Encoding.ASCII.GetBytes(data);
                PingOptions pingoptns = new PingOptions(128, true);
                Console.WriteLine("send : {0}", ip);
                ping.SendAsync(ip, TIMEOUT, buffer, pingoptns, item);
            }

            waiter.WaitOne();
        }
        private void PingCompletedCallback (object sender, PingCompletedEventArgs e)
        {
            lock (thisLock)
            {

                DataRow row = null;
                try
                {
                    row = e.UserState as DataRow;
                    string sendIP = row.Field<string>("IP");
                    string replyIP = e.Reply.Address.ToString();
                    Console.WriteLine("reply IP : {0}, send IP : {1}", replyIP, sendIP);
                    // If the operation was canceled, display a message to the user.
                    if (e.Cancelled)
                    {
                        row.SetField<bool>("Canceled", true);
                        return;
                    }

                    // If an error occurred, display the exception to the user.
                    if (e.Error != null)
                    {
                        if (row["Error"] == DBNull.Value) row["Error"] = new List<string>();
                        row.Field<List<string>>("Error").Add(e.Error.Message);
                    }
                    if (e.Reply.Status == IPStatus.TimedOut)
                    {
                        row["TimeOut"] = row.Field<int>("TimeOut") + 1;
                    }
                    else
                    {
                        if (row["Reply"] == DBNull.Value) row["Reply"] = new List<PingReply>();
                        row.Field<List<PingReply>>("Reply").Add(e.Reply);
                        row["Received"] = row.Field<int>("Received") + 1;
                    }

                    row["Sent"] = row.Field<int>("Sent") - 1;
                    if (row.Field<int>("Sent") > 0)
                    {
                        Ping ping = new Ping();
                        string ip = row.Field<string>("IP");
                        ping.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);
                        byte[] buffer = Encoding.ASCII.GetBytes(data);
                        PingOptions pingoptns = new PingOptions(128, true);
                        Console.WriteLine("send : {0}", ip);
                        ping.SendAsync(ip, TIMEOUT, buffer, pingoptns, row); ;
                    }
                    else
                    {
                        pingDict.Remove(sendIP);
                        if (pingDict.Count == 0) waiter.Set();
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception : {0}", ex.Message);
                }
            }
        }
    }

}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • Thanks, I make some modifications to the example code at https://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping(v=vs.110).aspx . It's faster with active hardware but not with inactives – U. Angel Feb 06 '18 at 20:08
  • The msdn sample is using a timeout of 12 seconds while my code is using 30 seconds.. Changing timeout in my code to 12 will make faster. I based my code on the msdn sample and then used your foreach loop. There should be no differences in my code and the msdn sample with active code. – jdweng Feb 06 '18 at 21:49
  • Even better. Update to send multiple times. – jdweng Feb 08 '18 at 05:24
0

I'm trying this way (the code is getting better)

    using System;
using System.Text;
using System.Net;
using System.Net.NetworkInformation;
using System.ComponentModel;
using System.Threading;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Configuration;
using System.Threading.Tasks;

namespace pingtask
{
    class Program
    {
        static void Main(string[] args)
        {

            Task task = new Task(makePing);
            task.Start();
            task.Wait();
            Console.WriteLine("Test finished.");
            Console.ReadLine();

        }

        static async void makePing()
        {

            Ping ping = new Ping();
            byte[] buffer = new byte[32];
            PingOptions pingoptns = new PingOptions(128, true);
            int timeOut = 4000;

            List<string> list_Eq = new List<string>();
            list_Eq.Add("192.168.23.33");
            list_Eq.Add("192.168.0.11");
            list_Eq.Add("192.168.0.7");
            list_Eq.Add("192.168.0.8");
            list_Eq.Add("192.168.0.9");
            list_Eq.Add("192.168.0.5");
            list_Eq.Add("192.168.0.1");
            list_Eq.Add("192.168.0.2");
            list_Eq.Add("192.168.0.3");
            list_Eq.Add("192.168.0.10");
            list_Eq.Add("192.168.0.14");
            list_Eq.Add("192.168.0.4");

            foreach (var item in list_Eq)
            {
                Console.WriteLine("ADDRESS:" + item);
                PingReply reply = await ping.SendPingAsync(item, timeOut, buffer, pingoptns);
                Console.WriteLine("TIME:" + reply.RoundtripTime);
                Console.WriteLine("==============================");
            }

        }
    }
}

Now I have a doubt, my code is something like "ping -n 1"? I mean if I want to do "ping -n 4" I should do it into a loop?

U. Angel
  • 3
  • 3
  • Use my code and add another row to DataTable called COUNT. Then set count to 4. When you reach the callback function subtract one from count and send another ping until count = zero. – jdweng Feb 07 '18 at 21:43