Jump to content

_Multiping : ping multiples hosts simultaneously


jguinch
 Share

Recommended Posts

Here are 4 small function that I use for a tool in my job to launch several ping simultaneously. It also offers the possibility to run in background
 - _Multiping
 - _MultiPingCancel
 - _MultipingGetInfo
 - _MultiPingGetResult

_Multiping requires the use of the #pragma compile(AutoItExecuteAllowed, True) directive.

 

#pragma compile(AutoItExecuteAllowed, True)

#include <ProcessConstants.au3>
#include <WinAPI.au3>
#include <WinAPIProc.au3>


; #EXAMPLE# =====================================================================================================================
#include <Array.au3>
ConsoleWrite("Downloading hosts list, please wait...")
Local $aDomains = StringRegExp(BinaryToString(InetRead("https://github.com/opendns/public-domain-lists/blob/master/opendns-random-domains.txt")), 'js-file-line">([^<]+)</td>', 3)
Redim $aDomains[25]

Local $iProgress = 0, $iCount = UBound($aDomains), $aMPInfos, $iPercent
Local $aPings = _Multiping($aDomains, 1000, 5, 1)
ProgressOn("PING HOSTS", "Please wait while _Multiping is running")

While 1
    $aMPInfos = _MultipingGetInfo(1)
    If Not $aMPInfos[0] Then ExitLoop
    $iPercent = Floor($aMPInfos[1]* 100 / $iCount)
    ProgressSet($iPercent, $aMPInfos[1] & " / " & $iCount & " done")
    Sleep(100)
WEnd
ProgressOff()
MsgBox(0, "_Multiping example", "Result :" & @CRLF & $aMPInfos[2] & " hosts are online")
Local $aRes = _MultiPingGetResult()
_ArrayDisplay($aRes)
; ===============================================================================================================================





; #FUNCTION# ====================================================================================================================
; Name ..........: _Multiping
; Description ...: Pings a list of hosts using simultaneous pings to increase the speed.
; Syntax ........: _Multiping($aHosts[, $iTimeout = 4000[, $iMaxPing = 5[, $iBackground = 0]]])
; Parameters ....: $aHosts              - 1D array containing the list of the hosts to ping.
;                  $iTimeout            - [optional] Time to wait for an answer in milliseconds (default is 4000).
;                  $iMaxPing            - [optional] Maximum number of simultaneous ping to launch (defaut is 5).
;                  $iBackground         - [optional] 0 - Waits until the ping process is conplete before continuing (defaut)
;                                                    1 - Returns immediately and launch the ping process in the background (see remarks)
; Return values .: 1 on success, 0 on error and sets @error to a non-zero value. See remarks.
; Rermarks ......: Use _MultipingGetInfo to determine if the _Multiping process is finish.
;                  Use _MultiPingGetResult to get the result of the previous _Multiping call.
;                  Use _MultiPingCancel to cancel a _Multiping process running in background.
;                  The function requires the use of the #pragma compile(AutoItExecuteAllowed, True) directive.
; ===============================================================================================================================
Func _Multiping($aHosts, $iTimeout = 4000, $iMaxPing = 5, $iBackground = 0)
    If Not IsDeclared("_iMultipingState") Then
        Global $g__aMPHosts, $g__iMPMaxPing, $g__iMPTimeout, $g__iMPState, $g__iMPFinished, $g__aMPRet, $g__iMPCount, $g__iMPCancel, $g__iMPCountOnline
    EndIf

    If $g__iMPState Then Return SetError(2, 0, 0)
    $g__aMPHosts = $aHosts
    $g__iMPMaxPing = $iMaxPing
    $g__iMPTimeout = $iTimeout
    $g__iMPCount = 0
    $g__iMPState = 1
    $g__iMPFinished = 0
    $g__iMPCountOnline = 0

    Local $aRet[UBound($aHosts)][2]
    $g__aMPRet = $aRet

    AdlibRegister("__MultipingAdlib", 100)

    If Not $iBackground Then
        While $g__iMPState
            Sleep(10)
        WEnd
    EndIf
    Return 1
EndFunc ; ==> _Multiping

; #FUNCTION# ====================================================================================================================
; Name ..........: _MultiPingCancel
; Description ...: Cancels a _Multiping porocess running in backgorund.
; Syntax ........: _MultiPingCancel()
; Parameters ....: None
; Return values .: 1 on success, 0 on error.
; ===============================================================================================================================
Func _MultiPingCancel()
    If Not IsDeclared("g__iMPCancel") Then Return 0
    $g__iMPCancel = 1
    Return 1
EndFunc ; ==> _MultiPingCancel

; #FUNCTION# ====================================================================================================================
; Name ..........: _MultipingGetInfo
; Description ...: Returns information for the previous _Multiping call
; Syntax ........: _MultipingGetInfo([$iFlag = 0])
; Parameters ....: $iFlag               - [optional] argument that determines what the return value will be. See Return Value.
; Return values .: The return value depends of the $iFlag value :
;                   $iFlag = 0 (default) : 1 if the _Multiping process is running, or 0 if finish
;                   $iFlag = 1 : a 1D array containing the following informations :
;                       array[0] : 1 if the _Multiping process is running, or 0 if finish
;                       array[1] : number of hosts processed by _Multiping
;                       array[1] : number of online hosts processed by _Multiping
; Remarks .......: _MultipingGetInfo is useful to retrieve the progress of a _Multiping running in background
; ===============================================================================================================================
Func _MultipingGetInfo($iFlag = 0)
    Local $iState = Execute("$g__iMPState")
    If Not $iFlag Then Return $iState

    Local $aRet = [$iState, Execute("$g__iMPFinished"), Execute("$g__iMPCountOnline") ]
    Return $aRet
EndFunc ; ==> _MultipingGetInfo

; #FUNCTION# ====================================================================================================================
; Name ..........: _MultiPingGetResult
; Description ...: Returns the result of the previous _Multiping call
; Syntax ........: _MultiPingGetResult([$iFlag = 0])
; Parameters ....: $iFlag               - [optional] Specifies whether to return pingable, not pinbable or all hosts. Default is 0.
;                                          - 0 : returns all results
;                                          - 1 : returns only pingable hosts
;                                          - 2 : returns only not pingable hosts
; Return values .: ;  On success, a 2D array containing results :
;                       array[0][0] : first hosts
;                       array[0][1] : result for the first host (see remarks)
;                       array[1][0] : second hosts
;                       array[1][1] : result for the second host
;                     On error, 0 and sets @error to a nonzero value.
; Remarks .......: A result can be a one of the following :
;                     - a positive value for the roundtrip-time in milliseconds.
;                     - one of theses negative values if the host is not pingable :
;                         -1 : Hosts is offline
;                         -2 : Host is unreachable
;                         -3 : Bad destination
;                         -4 : Other error
;                     -  0 if the ping process was cancelled before the host was pinged (only when using _MultiPing in background
; ===============================================================================================================================
Func _MultiPingGetResult($iFlag = 0)
    Local $aRes = Execute("$g__aMPRet")
    If Not IsArray($aRes) Then Return SetError(1, 0, 0)

    If $iFlag <> 0 And $iFlag <> 1 And $iFlag <> 2 Then Return SetError(2, 0, 0)

    Local $aRet[UBound($aRes)][2], $n = 0
    For $i = 0 To UBound($aRes) - 1
        If $aRes[$i][1] = "" Or StringInStr($aRes[$i][1], "PING:") Then $aRes[$i][1] = 0

        If $iFlag = 0 Or ($iFlag = 1 And $aRes[$i][1] > 0) Or ($iFlag = 2 And $aRes[$i][1] < 0) Then
            $aRet[$n][0] = $aRes[$i][0]
            $aRet[$n][1] = $aRes[$i][1]
            $n += 1
        EndIf
    Next
    Redim $aRet[$n][2]
    Return $aRet
EndFunc ; ==> _MultiPingGetResult

; #INTERNAL USE ONLY#============================================================================================================
Func __MultipingAdlib()
    Local $iPid, $iRet, $aResult
    Local Const $STILL_ACTIVE = 259

    For $i = 0 To UBound($g__aMPRet) - 1
        $g__aMPRet[$i][0] = $g__aMPHosts[$i]
    Next

    For $i = 0 To UBound($g__aMPRet) - 1
        If $g__aMPRet[$i][1] = "" Then
            If $g__iMPCount < $g__iMPMaxPing Then
                If $g__aMPHosts[$i] = "" Then Return SetError(1, 0, 0)
                $iPid = Run(@AutoItExe & ' /AutoIt3ExecuteLine "Exit Ping(""' & $g__aMPHosts[$i] & '"", ' & $g__iMPTimeout & ') & @error"')
                $g__aMPRet[$i][1] = "PING:" & _WinAPI_OpenProcess($PROCESS_QUERY_LIMITED_INFORMATION, 0, $iPID)
                $g__iMPCount +=1
            Else
                ExitLoop
            EndIf
        Else
            If StringInStr($g__aMPRet[$i][1], "PING:") Then
                $hProcess = StringReplace($g__aMPRet[$i][1], "PING:", "")
                $iRet = _WinAPI_GetExitCodeProcess($hProcess)
                If $iRet <> $STILL_ACTIVE Then
                    $aResult = StringRegExp($iRet, "(\d*)(\d)$", 1)
                    $g__aMPRet[$i][1] = ($aResult[0] ? $aResult[0] : (-1 * $aResult[1]))
                    $g__iMPFinished += 1
                    If $g__aMPRet[$i][1] > 0 Then $g__iMPCountOnline += 1
                    $g__iMPCount -= 1
                EndIf
            EndIf
            If $g__iMPCancel Then ExitLoop
        EndIf
    Next
    If $g__iMPFinished = UBound($g__aMPHosts) Or $g__iMPCancel Then
        AdlibUnRegister("__MultipingAdlib")
        $g__aMPHosts = 0
        $g__iMPMaxPing = 0
        $g__iMPTimeout = 0
        $g__iMPState = 0
        $g__iMPCancel = 0
    EndIf
EndFunc ; ==> __MultipingAdlib

 

Link to comment
Share on other sites

On 9/8/2016 at 5:16 AM, jguinch said:

$iPid = Run(@AutoItExe & ' /AutoIt3ExecuteLine "Exit Ping(""' & $g__aMPHosts[$i] & '"", ' & $g__iMPTimeout & ') & @error"')

why not just have a function return the the ping ?. That way the pragma declaration is not needed.
Am I wrong ?

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...