Ping.SendAsync () is always successful, even if the client is not pingable in cmd

I am trying to ping multiple IP addresses in C # using the Ping.SendAsync () method. I have a treeView with 5 IP addresses and using the SendAsync () method for each node. Here you can see:

private void Form1_Load(object sender, EventArgs e) { byte[] buffer = Encoding.ASCII.GetBytes("."); PingOptions options = new PingOptions(50, true); AutoResetEvent reset = new AutoResetEvent(false); Ping ping = new Ping(); ping.PingCompleted += new PingCompletedEventHandler(ping_Complete); foreach (TreeNode node in treeView1.Nodes) { ping.SendAsync(node.Text, 5000, buffer, options, reset); } } private void ping_Complete(object sender, PingCompletedEventArgs k) { foreach (TreeNode node in treeView1.Nodes) { PingReply reply = k.Reply; if (reply.Status == IPStatus.Success) { node.Text = node.Text + " (OK)"; } else { node.Text = node.Text + " (FAILED)"; } } } 

The problem is that ping is always successful. I have 2 clients that were online and pingable. The other 3 are offline, not pingable (in cmd I could not ping these clients). Therefore, it should display this:

 IP1 (OK) IP2 (FAILED) IP3 (FAILED) IP4 (OK) IP5 (FAILED) 

But exit 5 times "(OK)".

Any suggestions?:)

+6
source share
3 answers

I think John has the right explanation for your problem.

My suggestion is that you use the SendPingAsync method SendPingAsync ; it returns a Task<PingReply> , which you can expect (you also need to make your method asynchronous):

 private async void Form1_Load(object sender, EventArgs e) { byte[] buffer = Encoding.ASCII.GetBytes("."); PingOptions options = new PingOptions(50, true); AutoResetEvent reset = new AutoResetEvent(false); Ping ping = new Ping(); ping.PingCompleted += new PingCompletedEventHandler(ping_Complete); foreach (TreeNode node in treeView1.Nodes) { var reply = await ping.SendPingAsync(node.Text, 5000, buffer, options, reset); if (reply.Status == IPStatus.Success) { node.Text = node.Text + " (OK)"; } else { node.Text = node.Text + " (FAILED)"; } } } 

(note that this approach requires .NET 4.5)


As pointed out in the comments by Mike z, the above approach will execute signals in series, not in parallel. If you want to do this in parallel, you can do something like this:

 private async void Form1_Load(object sender, EventArgs e) { byte[] buffer = Encoding.ASCII.GetBytes("."); PingOptions options = new PingOptions(50, true); AutoResetEvent reset = new AutoResetEvent(false); Ping ping = new Ping(); ping.PingCompleted += new PingCompletedEventHandler(ping_Complete); var tasks = List<Task>(); foreach (TreeNode node in treeView1.Nodes) { var task = PingAndUpdateNodeAsync(ping, node); tasks.Add(task); } await Task.WhenAll(tasks); } private async Task PingAndUpdateNodeAsync(Ping ping, TreeNode node) { var reply = await ping.SendPingAsync(node.Text, 5000, buffer, options, reset); if (reply.Status == IPStatus.Success) { node.Text = node.Text + " (OK)"; } else { node.Text = node.Text + " (FAILED)"; } } 
+10
source

Each time you receive a PingCompleted event, you update all nodes in your tree the same way. Instead, you should only update the node corresponding to the IP address that the specific PingCompletedEventArgs . You might want to use node itself as the state argument in your SendAsync call so you can use it in an event handler.

I assume that you are either getting crashes, or updating everything with success, or not expecting long enough to see the crashes.

To verify that this is diagnostically correct, I suggest you separately log reply.Status somewhere that will not be overwritten.

Also, you are currently updating the user interface from a thread other than the UI, which is a very bad idea. Before updating it, you must return to the user interface thread.

+7
source

Fix Code:

 private void ping_Complete(object sender, PingCompletedEventArgs k) { foreach (TreeNode node in treeView1.Nodes) { PingReply reply = k.Reply; if(reply.Address.ToString()==node.Text) { if (reply.Status == IPStatus.Success) { node.Text = node.Text + " (OK)"; } else { node.Text = node.Text + " (FAILED)"; } } } } 
+2
source

Source: https://habr.com/ru/post/970684/


All Articles