Ping主机名需要太长时间(与Pinging IP地址相比)

时间:2018-04-14 03:53:04

标签: c# networking ping

我使用异步Ping来检查远程计算机是否可用(代码示例来自here)。我将其修改为使用List而不是IP范围。

这非常有用 IF 输入是IP地址列表(300多台主机为0,5秒)。但我需要检查一个主机名列表,这需要很长时间(300多个主机超过30秒)。

问题似乎是针对不可用主机的DNS名称解析。有办法解决它吗?

或者可能采用不同的方式来检查计算机是否在线(但必须使用主机名列表作为输入)。

编辑:我使用了他第三次尝试的代码,这就是为什么我直接链接到页面的那一部分。我可能应该更清楚

2 个答案:

答案 0 :(得分:1)

解析主机名的IP地址所需的时间比直接使用IP需要更多的时间。

选项包括:

  1. 并行执行ping。您链接的代码示例显示了如何执行此操作,但请确保您使用第3和第34节中的代码;第三次尝试:一个Ping来统治它们,一个Ping找到它们#34;而不是其中一个早期模式,如果你还没有。
  2. 我会猜测你是在重复做这个ping。如果是这种情况,那么在开始时进行一次DNS查找,然后从该点开始,您可以ping IP地址。例如Dns.GetHostAddresses

答案 1 :(得分:-1)

我在三月份写了下面的代码。所有ping都要完成12秒超时。如果所有ping完成,代码将更快完成。我还使用数据表作为我的ping列表,ping响应也进入表中,这样你就可以获得每次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[] { "192.168.1.1", 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);

            List<PingReply> replies = dt.AsEnumerable().Where(x => x.Field<List<PingReply>>("Reply") != null).Select(x => x.Field<List<PingReply>>("Reply")).SelectMany(x => x).ToList();

            long ShortTime = replies.Min(x => x.RoundtripTime);
        }
    }

    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);
                }
            }
        }
    }

}