Sign in to follow this  
Followers 0
lcty

Ping - not responding

10 posts in this topic

Hi guys,

I'm currently working on a little tool that pings a user-defined list of IPs (like servers, switches, etc.).

It will run on a server and writes its ping results to an .ini. An user front-end will display the results then.

All the actions will be repeated every user-defined amount of minutes (ie. all the commands run in an infinite loop).

Actually the script is working pretty good but after about 5 minutes the script stops responding.

It just seems to hang up.

I have no idea why this is happening. I hope you do :)

This is the main function executing the ping command:

Func exec()
; loads the user-defined IP list
    loadSystems()
    Local $dnsSuc = ""
    Local $ipSuc = ""
    Local $sTimestamp = @YEAR & @Mon & @MDAY & "_" & @HOUR & @MIN & @SEC
    Local $sLastSucDFS = ""
    Local $sLastSucIP = ""
; reads the last results of each system and pings...
    For $i=1 to UBound($systems)-1
        showLog("*Ping "& $systems[$i][1] & " @ " & $systems[$i][0] & " ...")
; ...the DNS name (also defined by user) // The var $iTO is the pingtimeout: 2000 msecs
        if $systems[$i][1] <> "" Then
            $tripDNS = ping($systems[$i][1], $iTO)
            if $tripDNS = 1 Then
                ;success 
                $dnsSuc = True
                $sLastSucDNS = $sTimestamp
            Else
                ; failed
                $dnsSuc = False
                $sLastSucDNS = $systems[$i][3]
            EndIf
        Else
            $sLastSucDNS = "n/a"
            $dnsSuc=""
        EndIf

;...the IP address
        $tripIP = ping($systems[$i][0], $iTO)
        if $tripIP = 1 Then
            ;success 
            $ipSuc = True
            $sLastSucIP = $sTimestamp
        Else
            ; failed
            $ipSuc = False
            $sLastSucIP = $systems[$i][2]
        EndIf   
        
        if $ipSuc = False Then
            If $senderror = "True" Then
                $date = $sLastSucIP
                if $date <> "reported" Then
                    if $date = "new" or $date="n/a" or $date="" or $date="Default" Then $date = "20130101_000000"
                    $dsplit = StringSplit($date, "")
                    $ndate = $dsplit[1] & $dsplit[2] & $dsplit[3] & $dsplit[4] & "/" & $dsplit[5] & $dsplit[6] & "/" & $dsplit[7] & $dsplit[8] & " " & $dsplit[10] & $dsplit[11] & ":" & $dsplit[12] & $dsplit[13] & ":" & $dsplit[14] & $dsplit[15]
                    $curr = _NowCalc()
                    If _DateDiff('s', $ndate, $curr) > $fail Then
                        ; send Error mail
                        showLog("   [ " & $systems[$i][0] & " did not respond. Sending Mail...")
                        sendMail($systems[$i][0], $sLastSucIP)
                        $sLastSucIP = "reported" ; set LSip so no multiple mails will be sent
                    EndIf   
                Else
                    showLog("   [ " & $systems[$i][0] & " did not respond. Already reported!")
                EndIf
            EndIf
        EndIf
        
; collect data and write to smasys.ini
        $sData = "DNS=" & $dnsSuc & @LF & "IP=" & $ipSuc & @LF & "LSdns=" & $sLastSucDNS & @LF & "LSip=" & $sLastSucIP & @LF & "refresh=" & $sTimestamp
        IniWriteSection($sRes, $systems[$i][0], $sData)
        
        checkSvc($systems[$i][0])
    Next    
EndFunc

And this is the loop:

;###################################
;## GUILoop
;###################################

While 1
    Local $pingnow = False
; those are commands you can submit from the front-end - not relevant for the issue, i guess    
    ; query actions
    $tmpAct = getAction()
    If $tmpAct = "0x0000" Then
        ; Do Nothing
    Elseif $tmpAct = "0x0001" Then
        ; Stop Loop
        $loop = False
        resetAction()
    Elseif $tmpAct = "0x0010" Then
        ; Ping now
        exec()
        $loop = True
        resetAction()
    ElseIf $tmpAct = "0x0011" Then
        ; reload Systems
        loadSystems()
        resetAction()
    ElseIf $tmpAct = "0x0100" Then
        ; reload Config
        loadServerConfig()
    ElseIf $tmpAct = "0x0101" Then
        ; clear Results
        FileDelete($sRes)
        IniWrite($sRes, "", "", "")
        resetAction()
    EndIf
; if the user wants to loop it's performing the following   
    ; System loop
    If $loop Then
; the amount of time the loop is repeated
        if _DateDiff("s", $timestamp, _NowCalc()) > $iRefresh Then
            $timestamp = _NowCalc() 
            $pingnow = False
; the function - see above
            exec()
            showLog("Waiting for further operations...")
            
            
        EndIf
    EndIf
    
; the GUI stuff (the server app has a little gui for the user to see what it's currently doing)
    ; GUI
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit;MsgBox(16, "Access Denied", "Please close the application by pressing the Quit-Button")
        Case $ButtonQuit
            Exit
        Case $ButtonStop
            if $loop Then 
                $loop = False
                GUICtrlSetData($ButtonStop, "Start loop")
            Else 
                $loop = True
                GUICtrlSetData($ButtonStop, "Stop loop")
            EndIf
        Case $ButtonMinimize
            GUISetState(@SW_MINIMIZE, $FormSrvGUI)
    EndSwitch
WEnd

Hope you guys understand what I'm doing here :)

If not please ask since I would be very happy if anyone has an idea why the script hangs up after a while :)

Thanks in advance!

best reagrds

lcty

Share this post


Link to post
Share on other sites



I would suggest starting by putting TrayIconDebug at the top of your script. This will help you figure out which line the script is "hanging" on, and can assist in troubleshooting.


√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites

Yeah, thanks mate. I didn't know of this feature - nice one.

Found out that it freezes in a totally different function than I expected.

After pinging I check for (user-defined) services running.

The essential code looks like this:

$pid = Run("sc \\" & $sDNS & " query " & $svcname, '', @SW_HIDE, 2)
Local $stdout       
            Do
                $stdout &= StdOutRead($pid)
            Until @error

Than it freezes at $stdout &= StdOutRead($pid).

The machine (stored in $sDNS) on which the script's checking for the service (stored in $svcname) is actually reachable. The service is running.

I suppose it is running into an infinite loop at this point.

Do you have any ideas for improving the code here??

Thanks!

Share this post


Link to post
Share on other sites

Yes, you have definitely created an infinite loop, which you will see if you put in a msgbox line after this line: $stdout &= StdOutRead($pid).

As for improving it, think about what you want it to do - you are currently saying "keep doing this until there is an error". Think about what you want the application to do and you should easily come up with a better Do...Until statement.


√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites

StdOutRead returns @error set to a non-zero number when the StdOut stream closes (i.e. it reaches EOF in the stream), his Do...Until loop should work the way it's written. Unless there's something in his script after the StdOutRead that wasn't posted in the snippet.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

BrewMan is correct, I forgot about the return of StdOutRead. This works just fine for me:

$sDNS = "MyServer"
$svcname = "PeerDistSvc"

$pid = Run("sc \\" & $sDNS & " query " & $svcname, '', @SW_HIDE, 2)
Local $stdout
            Do
                $stdout &= StdOutRead($pid)
            Until @error
Edited by JLogan3o13

√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites

Ok thanks guys.

I have still no solution for that. I just kept debugging and trying things - but without any improvement...

Anyway here's the whole function. Maybe you could see the mistake by your first look

Func checkSvc($sIP)
    Local $sTimestamp = @YEAR & @Mon & @MDAY & "_" & @HOUR & @MIN & @SEC
; Convert submitted IP address to DNS
    $sDNS = IniRead($sSys, $sIP, "DNS", Default)
; get all user-defined service IDs for this IP
    $serviceID = IniRead($sSys, $sIP, "service", Default)
    
    if not $serviceID = "" Then 
        $splitID = StringSplit($serviceID, ";")
; ... for every single service do...
        For $i=1 to $splitID[0] 
            $svcname = IniRead($sSvc, $splitID[$i], "name", Default)
            showLog("  -# Check service " & $svcname & " @ " & $sDNS & " ...")
            ; check for services running
            $pid = Run("sc \\" & $sDNS & " query " & $svcname, '', @SW_HIDE, 2)
            Local $stdout       

            Do
                $stdout &= StdOutRead($pid)
            Until @error        
; if the catched StdOut  has running in its string...           
            If StringInStr($stdout, "running") Then
                ; is running
                IniWrite($sSvc, $splitID[$i], "status", "True")
                IniWrite($sSvc, $splitID[$i], "LSres", $sTimestamp)
            Else
                IniWrite($sSvc, $splitID[$i], "status", "False")
                $currRes = IniRead($SSvc, $splitID[$i], "LSres", Default)
                if $currRes = "new" Then
                    IniWrite($sSvc, $splitID[$i], "LSres", "n/a")
                EndIf
            EndIf
        Next
    EndIf   
EndFunc

Share this post


Link to post
Share on other sites

The very first thing I would do would be to change your Run command, use @SW_SHOW instead of hide, so if there's an error you'll see it. You might even want to try including Run(@ComSpec & " /k " before your actual command to run so that it opens the console window and doesn't close it when it's done so you can see what's happening. 


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

Well, I found out that sometimes the StdOutRead returns an empty string. No idea why it's doing that.

Decided to make a workaround:

; check for services running
            $pid = Run("sc \\" & $sDNS & " query " & $svcname, '', @SW_HIDE, 2)
            Local $stdout   

            Do
                $stdout &= StdOutRead($pid)
                ConsoleWrite($stdout)
                if not $stdout = "" Then ExitLoop
            Until @error

Works for me.

Loads of thanks anyway!

Share this post


Link to post
Share on other sites

It will return hundreds of empty strings if you run it in a tight enough loop which that script is doing. It's not an issue, because they're actually just blank, they won't pad your $stdout variable with a bunch of blank lines.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
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
Sign in to follow this  
Followers 0