什么是在多个IP地址上运行连续ping的最佳方法

时间:2014-11-03 11:08:21

标签: vb.net loops ping

我有一个应用程序,目前针对大约60个不同的网关运行ping,以监控我的客户的互联网正常运行时间,因为我想知道他们的互联网是否会在他们之前退出。因此,目前我的应用程序运行从第一个开始的循环(运行4个ping)等待2秒,然后继续到下一个网关地址。然后,我已经实现了一些代码,如果ping导致失败,则会重试多次,因为我希望在发送警报之前100%确定他们的连接已关闭。

这种方法的问题是在再次扫描同一网关之前需要大约1或2分钟(或有时更长),这意味着如果连接是在ping之后直接退出,我不会知道差不多2分钟。我知道这听起来微乎其微,但我更愿意立即警告我的团队,以便他们立即采取行动。

因此,我的问题是:运行60个单独的ping(可能在不同的线程上)而不是循环遍历每个ping会更好(以及会产生什么影响)。这样我就可以同时在每个网关上运行连续ping。但是,我担心性能会对我的应用程序产生影响,以及是否会对系统造成太大的负担。

任何建议都将不胜感激。感谢

修改

我已经创建了以下代码,但它似乎对单个处理器内核产生了很大的影响,虽然这种方法可以正常运行,但它似乎认为GUI很快就会响应:

Public Sub PingHost()
    Try
        GatewayScanning = True
        For i As Integer = 0 To Gateways.Count - 1
            Dim t As New Threading.Thread(AddressOf CheckHostOnline)
            t.IsBackground = True
            t.Start(Gateways(i))
        Next

    Catch ex As Exception
        ErrorTrap(ex, "OfflineClientHandler: PingHost()")
    End Try
End Sub

Public Sub CheckHostOnline(ByVal gw As Object)
    Try
        Dim _gateway As Gateway_Object = DirectCast(gw, Gateway_Object)
        Dim pingSender As New Ping()
        Dim options As New PingOptions()
        'Dim averageTime As Integer
        Dim OfflinePingCount As Integer = 0

        ' Use the default Ttl value which is 128,
        ' but change the fragmentation behavior.
        options.DontFragment = False
        options.Ttl = 128

        ' Create a buffer of 32 bytes of data to be transmitted.
        Dim data As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        Dim buffer() As Byte = Encoding.ASCII.GetBytes(data)
        Dim timeout As Integer = 3000

        Do While Not GatewayScanning = False
            Dim reply As PingReply = pingSender.Send(_gateway.Gateway, timeout, buffer, options)

            If reply.Status = IPStatus.Success Then
                Dim resultTime As Integer = GetMs(CInt(reply.RoundtripTime))
                _gateway.Status = "ONLINE"
                _gateway.Result = resultTime
            Else
                OfflinePingCount += 1
                If OfflinePingCount < (My.Settings.OfflinePingCycleNumber * 4) Then
                    _gateway.Status = "TIMEOUT"
                    _gateway.Result = -1
                Else
                    _gateway.Status = "OFFLINE"
                    _gateway.Result = -1
                End If
            End If

            SyncLock class_OfflineGateways
                class_OfflineGateways.UpdateListView(_gateway)
            End SyncLock

            System.Threading.Thread.Sleep(2000)
        Loop
        pingSender.Dispose()

    Catch ex As Exception
        ErrorTrap(ex, "OfflineClientHandler: CheckHostOnline()")
    End Try

End Sub

1 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是在不同的线程上循环使用60个IP,并在再次开始循环之前需要5秒(或一段时间)的延迟。

另一种方法是使用异步ping而不是单独的线程。

上次我这样做时,我最终使用了单个线程,在ping之间有10毫秒的睡眠延迟。每当我将它们捆在一起时,有很多ping失败,无论是使用线程还是异步ping。我从未弄清楚问题是在服务器端还是在目标网络上。

这是我用来ping IP地址列表的类。它(以及其他一些东西)在ISP服务器上作为服务运行。 (我注意到我仍然宣布了背景工作者,尽管它已经不再使用了。)

Imports System.Net
Imports System.Threading
Imports System.Collections.Generic

Class pingGroup
' used to ping each IP in Targets

Public Targets As New List(Of IPAddress)
Public sectorID As Integer
Public nErrors As Integer = 0
Public Timeout As Integer = pingTimeout

Public PingLog As New List(Of String)
Public PingAvg As Integer = -2 ' -2 = uninit, -1 = error, else average ms excluding the slowest
Public PingTime As DateTime

Public pingCount As Integer = 0
Public pingStarts As Integer = 0
Dim msTotal As Integer = 0

Dim WithEvents bkgPing As System.ComponentModel.BackgroundWorker

Public Sub New(ByVal groupSectorID As Integer)
sectorID = groupSectorID
End Sub

Public Sub Ping()
' run a pingtest once, adding the result incrementally

Dim ip As IPAddress
Dim reply As NetworkInformation.PingReply
Dim ms As Integer

PingTime = Now

If PingLog.Count <= 0 Then PingLog.Add(Format(Now, "G") & " Ping Test")

For Each ip In Targets
  Using pPing As New NetworkInformation.Ping
    Try
      pingStarts = pingStarts + 1
      reply = pPing.Send(ip, Timeout)
      If reply.Status = NetworkInformation.IPStatus.Success Then
        ms = reply.RoundtripTime
        pingCount = pingCount + 1
        msTotal = msTotal + ms
        If pingCount > 0 Then PingAvg = msTotal / pingCount
        PingLog.Add(reply.Address.ToString & " " & ms)
      Else
        nErrors = nErrors + 1
        PingLog.Add(Format(Now, "G") & " ---Ping Error: " & ip.ToString & " " & reply.Status.ToString)
        End If

    Catch ex As Exception
      nErrors = nErrors + 1
      PingLog.Add(Format(Now, "G") & " ===Ping Error: " & ip.ToString & " " & ex.Message)
      End Try
    End Using
  Thread.Sleep(10)
  Next ip

End Sub

End Class