Ping.SendAsync()从0.0.0.0返回重播,如何获取ping地址?

我在C#中遇到Ping.SendAsync()函数的问题。 我ping一些ip地址,但有些错误。 我需要从列表中删除错误的地址。 但是如何,因为p_PingCompleted 事件args.replay.adress0.0.0.0 ? 这是我的代码:

System.Collections.Generic.List GameList = new System.Collections.Generic.List(); 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. 

您可以使用UserState属性和锁来确保对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); } } } } 

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

我认为它必须如何使用SendAsync(string, object)

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