Results 1 to 7 of 7

Thread: Pinging Multiple Machines

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Sep 2019
    Posts
    20

    Pinging Multiple Machines

    I'm very new to coding, and, as my first project - I am building my own portal to keep an eye on servers that I manage. I already have external software that does this, but thought it would be a great place to start.

    I've got a dashboard template with the servers in it and one of the column lines shows if the server is online or offline. I've used the below code to do it in the background and it alters the label text accordingly - but - the page takes a short while to load whilst (I assume) these functions complete. Is there a better way to do it?

    Code:
     If My.Computer.Network.Ping("109.200.30.43") Then
                Label1.ForeColor = Color.Green
                Label1.Text = ("Online")
            Else
                Label1.ForeColor = Color.Red
                Label1.Text = ("Offline")
            End If
    
            If My.Computer.Network.Ping("85.234.143.62") Then
                Label2.ForeColor = Color.Green
                Label2.Text = ("Online")
            Else
                Label2.ForeColor = Color.Red
                Label2.Text = ("Offline")
            End If
    
            If My.Computer.Network.Ping("185.141.207.136") Then
                Label3.ForeColor = Color.Green
                Label3.Text = ("Online")
            Else
                Label3.ForeColor = Color.Red
                Label3.Text = ("Offline")
            End If
    
            If My.Computer.Network.Ping("109.200.30.21") Then
                Label4.ForeColor = Color.Green
                Label4.Text = ("Online")
            Else
                Label4.ForeColor = Color.Red
                Label4.Text = ("Offline")
            End If
    
            If My.Computer.Network.Ping("91.186.9.244") Then
    
                Label5.ForeColor = Color.Green
                Label5.Text = ("Online")
            Else
                Label5.ForeColor = Color.Red
                Label5.Text = ("Offline")
            End If
    
            If My.Computer.Network.Ping("77.68.23.156") Then
                Label6.ForeColor = Color.Green
                Label6.Text = ("Online")
            Else
                Label6.ForeColor = Color.Red
                Label6.Text = ("Offline")
            End If
    
            If My.Computer.Network.Ping("77.68.77.244") Then
                Label7.ForeColor = Color.Green
                Label7.Text = ("Online")
            Else
                Label7.ForeColor = Color.Red
                Label7.Text = ("Offline")
            End If
    
            If My.Computer.Network.Ping("77.68.20.173") Then
                Label8.ForeColor = Color.Green
                Label8.Text = ("Online")
            Else
                Label8.ForeColor = Color.Red
                Label8.Text = ("Offline")
            End If

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Pinging Multiple Machines

    You say that that code is being used to do the work in the background and yet that code directly affects multiple controls. Those two things seem at odds. What exactly makes you think that that is happening in the background?

    If you want to call that Ping method then it is going to block, which means execution won't continue until it completes. You're calling it eight times so there will be eight delays. Even if you were to execute that code in a secondary thread, that thread will still take a while to complete because it is only checking one address at a time. If it was in a separate thread then you also should not be directly modifying controls.

    One option would be to call the Parallel.ForEach method. That will ping each address in parallel and then wait for them all to complete, which could reduce the execution time of that section of code by almost eight times:
    vb.net Code:
    1. Dim labelsByIPAddress As New Dictionary(Of String, Label)
    2.  
    3. labelsByIPAddress.Add("109.200.30.43", Label1)
    4. labelsByIPAddress.Add("85.234.143.62", Label2)
    5. 'Etc.
    6.  
    7. Parallel.ForEach(labelsByIPAddress,
    8.                  Sub(kvp)
    9.                      Dim ipAddress = kvp.Key
    10.                      Dim label = kvp.Value
    11.  
    12.                      Dim color As Color
    13.                      Dim text As String
    14.  
    15.                      If My.Computer.Network.Ping(ipAddress) Then
    16.                          color = Color.Green
    17.                          text = "Online"
    18.                      Else
    19.                          color = Color.Red
    20.                          text = "offline"
    21.                      End If
    22.  
    23.                      'Update the UI on the UI thread.
    24.                      label.BeginInvoke(Sub()
    25.                                            label.ForeColor = color
    26.                                            label.Text = text
    27.                                        End Sub)
    28.                  End Sub)

  3. #3
    Fanatic Member
    Join Date
    Jun 2019
    Posts
    557

    Re: Pinging Multiple Machines

    Hi. First to apologize that my post is not directly related to the title (Pinging multiple machines) but it is related to what the author wants: "I am building my own portal to keep an eye on servers that I manage".

    I created such monitoring application but it works the opposite way: servers are pinging the listening service (the monitoring machine). This is just different approach to the problem.

    The advantages for such solutions are:
    - No need of use of the standard PING protocol (ICMP ping) but using own service listening on TCP/IP port
    - No need of complex parallel PINGs - the monitoring app is only listening and process pings
    - No need to know server IPs so it is easy to add new servers and they can report their online status - no need of discovery feature
    - Servers can send more information to the monitor app, e.g. CPU/RAM/disk drives usage, own IP address, uptime, etc.
    - Easy calculation of last seen of servers allows flexible notifications, e.g. 5 secs timeout is warning (yellow), 30 seconds is disconnect/offline (red)
    - Easy sending additional information about the server, e.g. about the status of services internally running on the server so the monitoring app can show it

    Disadvantages:
    - You need access to these servers to be able to run the app that "pings" the monitoring server
    - You need to learn how to create own listening service, e.g. web service
    - Expose TCP/IP port to the public (from your example server IPs are public ones - please, edit your post and remove them)
    - It is good to encrypt the info sent. For web services you have to configure to use SSL (https protocol

    Instead of web services I am using pub-sub server (NATS or the pub-sub feature of Redis). Services are subscribing to a topic (like listening to a chat channel) and clients are sending info (publishing to the channel) so the services are receiving this info.

    Main advantage of such publish-subscribe pattern is that services (that listen) and clients (that send information) do not need to know IP addresses of each other.

    For the monitoring purpose it is very easy to add new servers that send their info to the monitoring application without knowing its IP - they just publish their status to the PING channel.

    Same can be applied for the monitoring application - it could be run on different machines (with different IPs) and still receive the information since they are subscribed to that PING topic. Just as example of this case is that you develop the app on your dev machine but later you deploy it on another machine where it will run and monitor servers' status. No need to reconfigure IPs, no need to do anything - it will just run and still receive the "ping" info:
    Name:  servers_monitor_pubsub.jpg
Views: 5672
Size:  20.9 KB

  4. #4

    Thread Starter
    Junior Member
    Join Date
    Sep 2019
    Posts
    20

    Re: Pinging Multiple Machines

    Quote Originally Posted by jmcilhinney View Post
    You say that that code is being used to do the work in the background and yet that code directly affects multiple controls. Those two things seem at odds. What exactly makes you think that that is happening in the background?

    If you want to call that Ping method then it is going to block, which means execution won't continue until it completes. You're calling it eight times so there will be eight delays. Even if you were to execute that code in a secondary thread, that thread will still take a while to complete because it is only checking one address at a time. If it was in a separate thread then you also should not be directly modifying controls.

    One option would be to call the Parallel.ForEach method. That will ping each address in parallel and then wait for them all to complete, which could reduce the execution time of that section of code by almost eight times:
    vb.net Code:
    1. Dim labelsByIPAddress As New Dictionary(Of String, Label)
    2.  
    3. labelsByIPAddress.Add("109.200.30.43", Label1)
    4. labelsByIPAddress.Add("85.234.143.62", Label2)
    5. 'Etc.
    6.  
    7. Parallel.ForEach(labelsByIPAddress,
    8.                  Sub(kvp)
    9.                      Dim ipAddress = kvp.Key
    10.                      Dim label = kvp.Value
    11.  
    12.                      Dim color As Color
    13.                      Dim text As String
    14.  
    15.                      If My.Computer.Network.Ping(ipAddress) Then
    16.                          color = Color.Green
    17.                          text = "Online"
    18.                      Else
    19.                          color = Color.Red
    20.                          text = "offline"
    21.                      End If
    22.  
    23.                      'Update the UI on the UI thread.
    24.                      label.BeginInvoke(Sub()
    25.                                            label.ForeColor = color
    26.                                            label.Text = text
    27.                                        End Sub)
    28.                  End Sub)
    Thankyou, this worked very well for me!

  5. #5

    Thread Starter
    Junior Member
    Join Date
    Sep 2019
    Posts
    20

    Re: Pinging Multiple Machines

    Quote Originally Posted by peterst View Post
    Hi. First to apologize that my post is not directly related to the title (Pinging multiple machines) but it is related to what the author wants: "I am building my own portal to keep an eye on servers that I manage".

    I created such monitoring application but it works the opposite way: servers are pinging the listening service (the monitoring machine). This is just different approach to the problem.

    The advantages for such solutions are:
    - No need of use of the standard PING protocol (ICMP ping) but using own service listening on TCP/IP port
    - No need of complex parallel PINGs - the monitoring app is only listening and process pings
    - No need to know server IPs so it is easy to add new servers and they can report their online status - no need of discovery feature
    - Servers can send more information to the monitor app, e.g. CPU/RAM/disk drives usage, own IP address, uptime, etc.
    - Easy calculation of last seen of servers allows flexible notifications, e.g. 5 secs timeout is warning (yellow), 30 seconds is disconnect/offline (red)
    - Easy sending additional information about the server, e.g. about the status of services internally running on the server so the monitoring app can show it

    Disadvantages:
    - You need access to these servers to be able to run the app that "pings" the monitoring server
    - You need to learn how to create own listening service, e.g. web service
    - Expose TCP/IP port to the public (from your example server IPs are public ones - please, edit your post and remove them)
    - It is good to encrypt the info sent. For web services you have to configure to use SSL (https protocol

    Instead of web services I am using pub-sub server (NATS or the pub-sub feature of Redis). Services are subscribing to a topic (like listening to a chat channel) and clients are sending info (publishing to the channel) so the services are receiving this info.

    Main advantage of such publish-subscribe pattern is that services (that listen) and clients (that send information) do not need to know IP addresses of each other.

    For the monitoring purpose it is very easy to add new servers that send their info to the monitoring application without knowing its IP - they just publish their status to the PING channel.

    Same can be applied for the monitoring application - it could be run on different machines (with different IPs) and still receive the information since they are subscribed to that PING topic. Just as example of this case is that you develop the app on your dev machine but later you deploy it on another machine where it will run and monitor servers' status. No need to reconfigure IPs, no need to do anything - it will just run and still receive the "ping" info:
    Name:  servers_monitor_pubsub.jpg
Views: 5672
Size:  20.9 KB
    Very interesting, gives me something to think about - thank you!

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Sep 2019
    Posts
    20

    Re: Pinging Multiple Machines

    Quote Originally Posted by peterst View Post
    Hi. First to apologize that my post is not directly related to the title (Pinging multiple machines) but it is related to what the author wants: "I am building my own portal to keep an eye on servers that I manage".

    I created such monitoring application but it works the opposite way: servers are pinging the listening service (the monitoring machine). This is just different approach to the problem.

    The advantages for such solutions are:
    - No need of use of the standard PING protocol (ICMP ping) but using own service listening on TCP/IP port
    - No need of complex parallel PINGs - the monitoring app is only listening and process pings
    - No need to know server IPs so it is easy to add new servers and they can report their online status - no need of discovery feature
    - Servers can send more information to the monitor app, e.g. CPU/RAM/disk drives usage, own IP address, uptime, etc.
    - Easy calculation of last seen of servers allows flexible notifications, e.g. 5 secs timeout is warning (yellow), 30 seconds is disconnect/offline (red)
    - Easy sending additional information about the server, e.g. about the status of services internally running on the server so the monitoring app can show it

    Disadvantages:
    - You need access to these servers to be able to run the app that "pings" the monitoring server
    - You need to learn how to create own listening service, e.g. web service
    - Expose TCP/IP port to the public (from your example server IPs are public ones - please, edit your post and remove them)
    - It is good to encrypt the info sent. For web services you have to configure to use SSL (https protocol

    Instead of web services I am using pub-sub server (NATS or the pub-sub feature of Redis). Services are subscribing to a topic (like listening to a chat channel) and clients are sending info (publishing to the channel) so the services are receiving this info.

    Main advantage of such publish-subscribe pattern is that services (that listen) and clients (that send information) do not need to know IP addresses of each other.

    For the monitoring purpose it is very easy to add new servers that send their info to the monitoring application without knowing its IP - they just publish their status to the PING channel.

    Same can be applied for the monitoring application - it could be run on different machines (with different IPs) and still receive the information since they are subscribed to that PING topic. Just as example of this case is that you develop the app on your dev machine but later you deploy it on another machine where it will run and monitor servers' status. No need to reconfigure IPs, no need to do anything - it will just run and still receive the "ping" info:
    Name:  servers_monitor_pubsub.jpg
Views: 5672
Size:  20.9 KB
    Very interesting, gives me something to think about - thank you!

  7. #7
    Fanatic Member
    Join Date
    Jun 2019
    Posts
    557

    Re: Pinging Multiple Machines

    Some example code of monitoring app and pinger app (that runs on "servers" that are monitored):

    Preliminary info:
    • Using Visual Studio 2017 or 2019
    • NATS pub-sub server downloaded from NATS Server Downloads
    • Running NATS server app (single executable) on a machine in the local network (for simplicity). To install as Windows Service just read the docs
    • By default no encryption, passwords or whatever security is set to NATS server


    For the projects:
    • Create two console projects - for Monitor and Pinger apps
    • For both projects add NuGet package of NATS.Client (by the NATS authors)


    Pinger app:
    VB.NET Code:
    1. Imports System.Net     ' For Dns.GetHostName
    2. Imports System.Text    ' For converting strings to bytes and vice versa
    3. Imports System.Threading
    4. Imports NATS.Client
    5.  
    6. Module Startup
    7.     Private _conn As IConnection
    8.     Private _channel As String = "PING.SERVERS"
    9.     Private _hostName As String
    10.  
    11.     Private Function GetNewConnection() As IConnection
    12.         Dim cf = New ConnectionFactory()
    13.         Dim opts = ConnectionFactory.GetDefaultOptions()
    14.         opts.Servers = {"xx.yy.aa.bb"}       ' Set IPs of NATS servers
    15.         '
    16.         ' Set other connection options here
    17.         '
    18.         Dim conn = cf.CreateConnection(opts)
    19.         Return conn
    20.     End Function
    21.  
    22.     Private Sub PingerTask()
    23.         _hostName = Dns.GetHostName
    24.         Dim msg As String
    25.         While True
    26.             Task.Delay(1000).Wait()                    ' Wait 1 second
    27.  
    28.             msg = $"{_hostName} {Date.Now.ToString()}"
    29.             _conn.Publish(_channel, Encoding.UTF8.GetBytes(msg))
    30.  
    31.         End While
    32.     End Sub
    33.  
    34.     Sub Main()
    35.         Console.WriteLine("Pinger Client Demo")
    36.         Console.WriteLine()
    37.  
    38.         Console.WriteLine("Connecting to NATS server...")
    39.  
    40.         _conn = GetNewConnection()
    41.  
    42.         Console.WriteLine("Starting pinger task")
    43.         Console.WriteLine("Press a key to exit...")
    44.         Dim cts = New CancellationTokenSource
    45.         Dim pinger = New Task(AddressOf PingerTask, cts.Token)
    46.         pinger.Start()
    47.  
    48.         Console.ReadKey()
    49.         cts.Cancel()
    50.  
    51.         _conn.Close()
    52.         _conn.Dispose()
    53.     End Sub
    54. End Module

    Monitoring app:
    VB.NET Code:
    1. Imports System.Text
    2. Imports NATS.Client
    3.  
    4. Module Startup
    5.     Private _conn As IConnection
    6.     Private _channel As String = "PING.SERVERS"
    7.  
    8.     Private Function GetNewConnection() As IConnection
    9.         Dim cf = New ConnectionFactory()
    10.         Dim opts = ConnectionFactory.GetDefaultOptions()
    11.         opts.Servers = {"xx.yy.aa.bb"}       ' Set IPs of NATS servers
    12.         '
    13.         ' Set other connection options here
    14.         '
    15.         Dim conn = cf.CreateConnection(opts)
    16.         Return conn
    17.     End Function
    18.  
    19.     Private Sub PingSubscriberTask(sender As Object, e As MsgHandlerEventArgs)
    20.         Dim msg = Encoding.UTF8.GetString(e.Message.Data)
    21.         Console.WriteLine(msg)
    22.     End Sub
    23.  
    24.     Sub Main()
    25.         Console.WriteLine("Pings Monitor Demo")
    26.         Console.WriteLine()
    27.  
    28.         Console.WriteLine("Connecting to NATS server...")
    29.  
    30.         _conn = GetNewConnection()
    31.  
    32.         Console.WriteLine("Starting monitor subscriber task")
    33.         Console.WriteLine("Press a key to exit...")
    34.  
    35.         Dim subscr = _conn.SubscribeAsync(_channel, AddressOf PingSubscriberTask)
    36.  
    37.         Console.ReadKey()
    38.  
    39.         _conn.Close()
    40.         _conn.Dispose()
    41.     End Sub
    42. End Module

    That's all. Run the monitor app on one machine. Then start the pinger app on multiple machines and watch the output inside monitoring app.

    If monitoring app is started on another machine (or as second instance on same) it will also receive the "pings". Even one copy of monitor is stopped (e.g. computer crashed), the other copy (running on another machine) will still receive the data and process it.

    Above examples are simplified for the purpose of this task but just give an overview how the task to monitor multiple servers can be achieved. Currently pinger clients are sending computer host name and local date/time.

    Clients (the pinger apps running on the "servers") can be in same local network, on VPN network or on internet - only NATS port should be opened (and forwarded for using on internet). Of course securing NATS server is very important when exposing it to internet.

    Adding more features to the apps is quite easy - just send serialized object as message (which is array of bytes) from pinger app and deserialize it in the monitor app. JSON or ProtoBuffers are in good use here. Serialized objects can contain a lot of info (as I already mentioned in my first reply):
    - Info about CPU, RAM, disks usage on the server - overloads are not OK so better to monitor them
    - Info for locally running on the server apps, e.g. some services as database server, web, ftp, etc. - keep in single message all that status
    - Temperatures info (if possible and provided by the specific hardware) - CPU, motherboard, disk drivers, etc.
    - Anything that is useful and needs to be monitored (and is possible to do easy via .NET code)

    Keeping list of last seen time of servers (on each received ping update the info in the clients list) will allow easy check if server is timed out for short time (5-10 seconds) or disconnected (for 30 seconds or more).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width