Jewtus

Trouble with multithreading and stdoutread

5 posts in this topic

#1 ·  Posted (edited)

I have a script that searches the network and finds the hostname of any IP that I'm trying to build but I'm running into a couple issues:

1) I put a counter in to limit the number of threads that runs but it doesn't seem to be working and I have no idea what I'm missing

2) The loop also reads stdout, but I think that the way I have my loop setup, its purging the stdout value if the process has finished

This is what I've been fooling around with:

#include <GUIConstantsEx.au3>
#include <array.au3>

$addresses=CheckNetwork()
_ArrayDisplay($addresses)

Func CheckNetwork() ;Uses local host
;Check for IP range to search
    $found = 0 ;how many active connections you have
    $localIP1 = @IPAddress1
    $localIP2 = @IPAddress2
    $localIP3 = @IPAddress3
    $localIP4 = @IPAddress4
    If $localIP1 <> "0.0.0.0" Then $found += 1
    If $localIP2 <> "0.0.0.0" Then $found += 1
    If $localIP3 <> "0.0.0.0" Then $found += 1
    If $localIP4 <> "0.0.0.0" Then $found += 1


    If $found > 1 Then ;if there is more than one network available you will be prompted to choose which to scan
        If $found <3 then
            GUICreate("Choose an IP range", 240, 55, (@DesktopWidth / 2) - 120, @DesktopHeight / 4)
        Else
            GUICreate("Choose an IP range", 240, 115, (@DesktopWidth / 2) - 120, @DesktopHeight / 4)
        EndIf
        $IPShow = StringSplit($localIP1, ".")
        $button1 = GUICtrlCreateButton($IPShow[1] & "." & $IPShow[2] & "." & $IPShow[3] & ".xxx", 5, 5, 110, 40)
        $IPShow = StringSplit($localIP2, ".")
        $button2 = GUICtrlCreateButton($IPShow[1] & "." & $IPShow[2] & "." & $IPShow[3] & ".xxx", 125, 5, 110, 40)
        $IPShow = StringSplit($localIP3, ".")
        $button3 = GUICtrlCreateButton($IPShow[1] & "." & $IPShow[2] & "." & $IPShow[3] & ".xxx", 5, 50, 110, 40)
        $IPShow = StringSplit($localIP4, ".")
        $button4 = GUICtrlCreateButton($IPShow[1] & "." & $IPShow[2] & "." & $IPShow[3] & ".xxx", 125, 50, 110, 40)
        If @IPAddress1 = "0.0.0.0" Then GUICtrlDelete($button1)
        If @IPAddress2 = "0.0.0.0" Then GUICtrlDelete($button2)
        If @IPAddress3 = "0.0.0.0" Then GUICtrlDelete($button3)
        If @IPAddress4 = "0.0.0.0" Then GUICtrlDelete($button4)
        GUISetState(@SW_SHOW, "Choose an IP range")
        Do
            $msg = GUIGetMsg()
            If $msg = $GUI_EVENT_CLOSE Then Exit
            If $msg = $button1 Then
                $chosenIP = @IPAddress1
                ExitLoop
            EndIf
            If $msg = $button2 Then
                $chosenIP = @IPAddress2
                ExitLoop
            EndIf
            If $msg = $button3 Then
                $chosenIP = @IPAddress3
                ExitLoop
            EndIf
            If $msg = $button4 Then
                $chosenIP = @IPAddress4
                ExitLoop
            EndIf
        Until 1 = 2
        GUIDelete("Choose an IP range")
    Else
        If $localIP1 <> "0.0.0.0" Then $chosenIP = $localIP1
        If $localIP2 <> "0.0.0.0" Then $chosenIP = $localIP2
        If $localIP3 <> "0.0.0.0" Then $chosenIP = $localIP3
        If $localIP4 <> "0.0.0.0" Then $chosenIP = $localIP4
    EndIf
    $oct = StringSplit($chosenIP, ".")
    $range = $oct[1] & "." & $oct[2] & "." & $oct[3] & "."
    Local $address[255][3]
    For $i = 0 To 254
        $address[$i][0] = $range & $i+1; generate IP
        $address[$i][1] = 0
        $address[$i][2] = 0
    Next
    $threads=5
    local $current=0,$total=UBound($address)-1,$counter=0
    ProgressOn("Working","Working")
    Do
        $sPercent=Round(($current/$total)*100,2)
        ProgressSet($sPercent,$sPercent&"%")
        For $i = 0 To UBound($address)-1
            $sIP=$address[$i][0]
            If $address[$i][1] = 0 and $counter < $threads then
                $cmdLine='"' & @ComSpec & '" /c "ping -n 1 -w 5 -a '&$sIP&'"'
                $address[$i][1] = Run($cmdLine, '', @SW_HIDE,$STDOUT_CHILD)
                $counter=$counter+1
            Elseif $address[$i][1] <> 0 Then
                If $address[$i][2]="" or $address[$i][2]=0 then $address[$i][2]=StdoutRead($address[$i][1])
                If ProcessExists($address[$i][1])=0 AND $counter>0 then
                    $counter=$counter-1
                    $current=$current+1
                EndIf
            EndIf
        Next
    Until $counter=0
    ProgressOff()
    Return $address
EndFunc

When I run this, it seems fine until one thread finishes and then it just fires every single other ping. It also doesn't seem to be saving the output in my array on a consistent basis (seems to purge the values when finished).

 

Am I missing something obvious?

Edited by Jewtus

Share this post


Link to post
Share on other sites



There are no threads in there.


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

when you generate the IP ranges, you should consider the subnet mask, you are instead supposing that exists only this mask 255.255.255.0.
Your loop to spawn ping commands is a bit messy... (also, running many ping.exe is not multithreading)
If you are interested, you could have a look here for a code that uses a similar way to spawn pings and that works correctly.. 

 

1 person likes this

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

fair enough... Multi-tasking

@Chimp that looks and works very well, but the one part I actually need out of it... I need the host name. When I run _nPing('192.168.183.1-255') to see what host names are on my direct network, I do get an array back, but I don't get any hostnames.

I have been running into issues with _TCPIpToName on windows 10 and that is why I reverted back to doing what I know.. command lines.

Edit: found the resolve flag... that seems to have worked.

Any reason I shouldn't change $MAX_PROCESS?

Edited by Jewtus

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