我有一个应用程序,目前针对大约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
答案 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