Ping.SendAsync () returned playback from 0.0.0.0, how to get ping address?

I have a problem with the Ping.SendAsync () function in C #. I ping several ip addresses, but some of them are mistaken. I need to remove the wrong addresses from the list. But how, because the p_PingCompleted event is args.replay.adress 0.0.0.0? Here is my code:

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

And the conclusion:

 Pinging 16.5.4.3... Ping reply from: 0.0.0.0 has 0 ms. 
+4
source share
3 answers

You can use the UserState property and lock to provide consistent access to the 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); } 

Then in your p_PingCompleted handler:

 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); } } } } 
+2
source

In an asynchronous call, send a Ping object (or a game object, any list that you work with) as the state of the object, and then from the ping completion event, simply remove this object from the list if the address is not valid.

+1
source

I think it should do the way you use SendAsync(string, object) .

On MSDN, it has a pretty good example. Instead, use SendAsync(String, Int32, Byte[], PingOptions, Object) or SendAsync(IPAddress, Int32, Byte[], PingOptions, Object) . Follow this example and it should work for you.

0
source

All Articles