【问题标题】:Ping.SendAsync() returned replay from 0.0.0.0, how to get pinged address?Ping.SendAsync() 从 0.0.0.0 返回重播,如何获取 ping 地址?
【发布时间】:2011-07-06 20:54:56
【问题描述】:

我对 C# 中的 Ping.SendAsync() 函数有疑问。 我ping了一些IP地址,但其中一些是错误的。我需要从列表中删除错误的地址。但是如何,因为 p_PingCompleted event args.replay.adress0.0.0.0? 这是我的代码:

System.Collections.Generic.List<Game> GameList = new System.Collections.Generic.List<Game>();
System.Timers.Timer timer = new System.Timers.Timer(5000);

        public StartServer()
        {
            this.tcpListener = new TcpListener(IPAddress.Any, 8888);
            this.listenThread = new Thread(new ThreadStart(ListenForClients));
            this.listenThread.Start();
            Console.WriteLine("Master server running...");
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
            timer.Start();
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Game[] games = GameList.ToArray();
            foreach (Game curgame in games)
            {
                System.Net.NetworkInformation.Ping p = new System.Net.NetworkInformation.Ping();
                p.PingCompleted += new System.Net.NetworkInformation.PingCompletedEventHandler(p_PingCompleted);
                p.SendAsync(IPAddress.Parse(curgame.IP), new object());
            }
            SendMessageToAll(output);
            Console.WriteLine("Timer.Elapsed with data [" + output + "]");
        }

        void p_PingCompleted(object sender, System.Net.NetworkInformation.PingCompletedEventArgs e)
        {
            Console.WriteLine("Ping reply from: " + e.Reply.Address.ToString() + " has " + e.Reply.RoundtripTime.ToString() + " ms.");
            if (e.Reply.RoundtripTime == 0 ||
                e.Reply.RoundtripTime >= 2500)
            {
                Console.WriteLine("   Removing this server because ping is 0 or is greater than 2500 ms");
            }
        }

输出是:

Pinging 16.5.4.3...
Ping reply from: 0.0.0.0 has 0 ms.

【问题讨论】:

    标签: c# .net networking asynchronous ping


    【解决方案1】:

    您可以使用UserState property 和锁来确保对GameList 的序列化访问:

    byte[] buffer = Encoding.ASCII.GetBytes (new string('a', 32));
    var options = new PingOptions (32, true);
    
    Ping p = new Ping();
    p.PingCompleted += p_PingCompleted;
    foreach (Game curgame in GameList.ToArray())
    {
        // e.UserState will be curgame
        p.SendAsync(IPAddress.Parse(curgame.IP), 2500, buffer, options, curgame);
    }
    

    然后在您的p_PingCompleted 处理程序中:

    void p_PingCompleted(object sender, PingCompletedEventArgs e)
    {
        var game = (Game)e.UserState;
        if (e.Reply.Status != IPStatus.Success)
        {
            Console.WriteLine(
                "  Could not reach {0} ({1}), removing this server...",
                game.IP,
                e.Reply.Status);
            lock (GameList)
            {
                GameList.Remove(game);
            }
        }
        else
        {
            Console.WriteLine(
                "Ping reply from: {0} in {1} ms",
                e.Reply.Address,
                e.Reply.RoundtripTime);
            if (e.Reply.RoundtripTime == 0 ||
                e.Reply.RoundtripTime >= 2500)
            {
                Console.WriteLine("  Ping too high, removing this server...");
                lock (GameList)
                {
                    GameList.Remove(game);
                }
            }
        }
    }
    

    【讨论】:

    • 这很好,但不能解释为什么他的 IP 得到 0.0.0.0。
    • @0A0D:我敢打赌,在这些情况下PingReply.Status 类似于无法到达的目的地。
    【解决方案2】:

    在异步调用中,发送 Ping 对象(或游戏对象,无论您正在处理的任何列表)作为对象状态,然后从 ping 完成事件中,如果地址无效,只需从列表中删除该对象.

    【讨论】:

    • 你的意思是p.SendAsync(IPAddress.Parse(curgame.IP), curgame);
    • 是的。只需在 ping 完成的代码中使用,GamesList.Remove(e.UserState);
    【解决方案3】:

    我认为这与您使用 SendAsync(string, object) 的方式有关。

    MSDN 有一个很好的例子。请改用SendAsync(String, Int32, Byte[], PingOptions, Object)SendAsync(IPAddress, Int32, Byte[], PingOptions, Object)。按照那个例子,它应该适合你。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-11
      • 1970-01-01
      • 2010-12-02
      • 2011-08-02
      • 1970-01-01
      • 2011-06-18
      • 1970-01-01
      • 2013-06-05
      相关资源
      最近更新 更多