TCPConnect Problem

  • Hallo,

    irgendwie komme ich nicht weiter ... da ich mich mal bissel mehr mit den TCP-Functions auseinander setzen wollte, habe ich mich mal an einem kl. Script versucht.

    Mein Problem bei diesem Script ist, dass anscheinend TCPConnect ziemlich langsam arbeitet. Da hilft auch kein TCPTimeOut zum einstellen (der ja eigentlich auch eh schon bei 100ms steht).

    Um das Problem dann genauer zu suchen, habe ich mal nur das nötigste in ein anderes Script verfrachtet ... und siehe da, da läuft es wesentlich schneller. Im Hauptscript habe ich dann noch versucht, soweit wie möglich noch was einzubauen, dass mich dem Fehler näher bringt ... und laut diesem, ist das Prob bei TCPConnect.

    Im Hauptscript wird zwar noch eine Start- und EndIP in eine Range umgerechnet (jede IP einzeln), aber das geht eigentlich relativ schnell.

    Also macht euch mal am besten einen Überblick über die beiden Scripte ... ich hoffe mir kann jmd sagen, wo das Prob liegt.

    1. Hauptscript (langsam)

    Spoiler anzeigen
    [autoit]

    #NoTrayIcon
    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Version=beta
    #AutoIt3Wrapper_icon=..\..\..\Icons\shell32.ico
    #AutoIt3Wrapper_Compression=4
    #AutoIt3Wrapper_UseUpx=n
    #AutoIt3Wrapper_Change2CUI=y
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $IPStart, $IPEnd
    Global $fBroadcast = False

    [/autoit] [autoit][/autoit] [autoit]

    $IPStart = "211.117.64.66"
    $IPEnd = "211.117.64.74"
    If Not _IsIPv4($IPStart) Or Not _IsIPv4($IPEnd) Then Exit
    $iPort = "8888"
    If $iPort <= 0 Or $iPort > 65535 Then Exit

    $sDelim = Opt("GuiDataSeparatorChar")
    Local $pattern = '(\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' & _
    '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)'
    If (Not StringRegExp($IPStart, $pattern, 0) Or Not StringRegExp($IPEnd, $pattern, 0)) Then Exit

    [/autoit] [autoit][/autoit] [autoit]

    $sock = ""

    [/autoit] [autoit][/autoit] [autoit]

    TCPStartup()
    $timer = TimerInit()

    [/autoit] [autoit][/autoit] [autoit]

    Local $var = StringSplit($IPStart, '.')
    Local $o1 = $var[1], $o2 = $var[2], $o3 = $var[3], $o4 = $var[4]
    $var = StringSplit($IPEnd, '.')
    Local $e1 = $var[1], $e2 = $var[2], $e3 = $var[3], $e4 = $var[4]
    Local $start = 1, $end = 255
    If $fBroadcast Then
    $start = 0
    $end = 256
    EndIf
    While $o1 <= $e1
    While ($o2 <= $e2) Or ($o1 < $e1)
    If $o2 = $end Then
    $o1 += 1
    $o2 = $start
    EndIf
    While ($o3 <= $e3) Or ($o2 < $e2) Or ($o1 < $e1)
    If $o3 = $end Then
    $o2 += 1
    $o3 = $start
    EndIf
    While True
    $IP = $o1 & '.' & $o2 & '.' & $o3 & '.' & $o4;TCPNameToIP($IP)
    MsgBox(0, "generate", $ip & @CRLF & Round(TimerDiff($timer), 2))

    [/autoit] [autoit][/autoit] [autoit]

    $timer = TimerInit()
    $sock = TCPConnect($IP, $iPort)
    If Not @error Then
    MsgBox(0, "OK", $ip & @CRLF & Round(TimerDiff($timer), 2))
    Else
    MsgBox(0, "Fail", $ip & @CRLF & Round(TimerDiff($timer), 2))
    EndIf
    TCPCloseSocket($sock)
    $timer = TimerInit()
    If ($o1 = $e1) And ($o2 = $e2) And ($o3 = $e3) And ($o4 = $e4) Then
    TCPShutdown()
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $o4 += 1
    If $o4 = $end Then
    $o3 += 1
    $o4 = $start
    EndIf
    WEnd
    WEnd
    WEnd
    WEnd

    Func _IsIPv4(Const $S_IP)
    If StringRegExp($S_IP, "\A(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])\z") Then Return (1)
    Return (SetError(1, 0, 0))
    EndFunc ;==>_IsIPv4

    [/autoit]

    2. Teilscript (nur die wichtigsten Funktionen) (schnell)

    Spoiler anzeigen
    [autoit]


    $sock = ""
    $iport = "8888"

    [/autoit] [autoit][/autoit] [autoit]

    Dim $Ip[10]
    $Ip[0] = 9
    $Ip[1] = "211.117.64.66"
    $Ip[2] = "211.117.64.67"
    $Ip[3] = "211.117.64.68"
    $Ip[4] = "211.117.64.69"
    $Ip[5] = "211.117.64.70"
    $Ip[6] = "211.117.64.71"
    $Ip[7] = "211.117.64.72"
    $Ip[8] = "211.117.64.73"
    $Ip[9] = "211.117.64.74"

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $Ip[0]
    $timer = TimerInit()
    $sock = TCPConnect($IP[$i], $iPort)
    If Not @error Then
    MsgBox(0, "", $IP[$i] & ":" & $iPort & @CRLF & Round(TimerDiff($timer), 2) & "ms")
    Else
    MsgBox(0, "ERROR", $IP[$i] & ":" & $iPort & @CRLF & Round(TimerDiff($timer), 2) & "ms")
    EndIf
    TCPCloseSocket($sock)
    Next

    [/autoit]
  • Hey, hat keiner nen Tip?

    mir ist noch was eingefallen ... und zwar du ursprüngliche Funktion von BugFix zu nutzen und vorher die Range generieren zu lassen, mit folgendem Script:

    Spoiler anzeigen
    [autoit]

    #NoTrayIcon
    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Version=beta
    #AutoIt3Wrapper_icon=..\..\..\Icons\shell32.ico
    #AutoIt3Wrapper_Compression=4
    #AutoIt3Wrapper_UseUpx=n
    #AutoIt3Wrapper_Change2CUI=y
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $Range = _GenerateIPsInRange("211.117.64.66", "211.117.64.74")

    [/autoit] [autoit][/autoit] [autoit]

    $iPort = "8888"

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $Range[0]
    $IP = $Range[$i]
    $timer = TimerInit()
    $sock = TCPConnect($IP, $iPort)
    If Not @error Then
    MsgBox(0, "OK", $ip & @CRLF & Round(TimerDiff($timer), 2))
    Else
    MsgBox(0, "Fail", $ip & @CRLF & Round(TimerDiff($timer), 2))
    EndIf
    TCPCloseSocket($sock)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Func _IsIPv4(Const $S_IP)
    If StringRegExp($S_IP, "\A(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])\z") Then Return (1)
    Return (SetError(1, 0, 0))
    EndFunc ;==>_IsIPv4

    [/autoit] [autoit][/autoit] [autoit]

    ;-------------------------------------------------------------------------------------------------
    ; Function _GenerateIPsInRange($IPstart, $IPend, $iRetType=0, $sDelim=Default, $fBroadcast=False)
    ; Description Erstellt alle möglichen IP's zwischen $IPstart und $IPend
    ; Parameter $IPstart erste IP im Bereich
    ; $IPend letzte IP im Bereich
    ; $iRetType Return-Type 0-Array (Standard), 1-String, trennzeichenbasiert
    ; $sDelim Trennzeichen bei Stringausgabe, Default= Zeichen von Opt("GuiDataSeparatorChar")
    ; Return Succes Array 1D (Anzahl in $a[0]) oder String mit allen erstellten IP's
    ; Failure 0 und set @error 1 : übergebene IP nicht korrekt
    ; Author BugFix ([email='bugfix@autoit.de'][/email])
    ;----------------------------------------------------------------------------------------------------------------------
    Func _GenerateIPsInRange($IPstart, $IPend, $iRetType=0, $sDelim=Default, $fBroadcast=False)
    If IsKeyword($sDelim) Then $sDelim = Opt("GuiDataSeparatorChar")
    Local $pattern = '(\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'& _
    '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)'
    If ( Not StringRegExp($IPstart, $pattern, 0) Or _
    Not StringRegExp($IPend, $pattern, 0) ) Then
    SetError(1)
    Return 0
    EndIf
    Local $var = StringSplit($IPstart, '.')
    Local $o1 = $var[1], $o2 = $var[2], $o3 = $var[3], $o4 = $var[4]
    $var = StringSplit($IPend, '.')
    Local $e1 = $var[1], $e2 = $var[2], $e3 = $var[3], $e4 = $var[4]
    Local $sOut = '', $start = 1, $end = 255
    If $fBroadcast Then
    $start = 0
    $end = 256
    EndIf
    While $o1 <= $e1
    While ($o2 <= $e2) Or ($o1 < $e1)
    If $o2 = $end Then
    $o1 += 1
    $o2 = $start
    EndIf
    While ($o3 <= $e3) Or ($o2 < $e2) Or ($o1 < $e1)
    If $o3 = $end Then
    $o2 += 1
    $o3 = $start
    EndIf
    While True
    $sOut &= $o1 &'.'& $o2 &'.'& $o3 &'.'& $o4 & $sDelim
    If ($o1 = $e1) And ($o2 = $e2) And ($o3 = $e3) And ($o4 = $e4) Then
    If $iRetType Then
    Return $sOut
    Else
    Return StringSplit(StringTrimRight($sOut, StringLen($sDelim)), $sDelim, 1)
    EndIf
    EndIf
    $o4 += 1
    If $o4 = $end Then
    $o3 += 1
    $o4 = $start
    EndIf
    WEnd
    WEnd
    WEnd
    WEnd
    EndFunc ;==>_GenerateIPsInRange

    [/autoit]

    Das Script ist übrigens auch schnell ... was ich nicht verstehe. das würde nun wiederrum bedeuten, dass es an der IP-Erstellung in meinem Mainscript liegt (wobei die IP-Erstellung aus Script 3 ja auch durchgeführt wird und sehr schnell abgeschlossen ist). UND laut Timer und MsgBox geht die IP-Erstellung ja auch im Mainscript schnell ... nur TCPConnect eben nicht. Irgendwie scheint hier das zusammenspiel Probleme zu machen, oder?

  • die unterhaltung ist zwar sehr monoton, aber ich hab nun folgendes als lösung.
    ich lasse mit der function von bugfix die range ganz normal erstellen, lasse aber jede ip in ein textfile schreiben (da ich auf ein array während der funktion anscheinend nicht zugreifen kann).

    dann lass ich bei adblibenable/ -register aus der txt immer die nächste zeile auslesen ... dann ist die schnelligkeit des scripts wieder super (hoffe die auslastung geht auch, dass muss ich nochmal checken)

  • hmm, also jetzt habe ich das problem wirklich gefunden ... denn bei den testscripten war das ergebnis immer so schnell, da dort keine TCPStartup aufgerufen wurde.

    wenn das ebenfalls drin steht, brauchen die scripte auch so lange.

    aber, was ich nicht verstehe, wie kann es sein, dass das ergebnis des timer > 20.000 ms ist, wenn doch TCPTimeout auf 100 ms (oder manuell sogar auf 10 ms) steht???

  • Hey,

    ich glaube ich habe ein Verständnisproblem mit TCPTimeout "gehabt". Ich dachte, wenn solange keine Anwort kommt, bricht TCPConnect ab ... aber anscheinend wird dann nochmal ein neuees Paket geschickt.

    Nun gut, ich habe nen Timer laufen und könnte per Adlib prüfen, ob der Timer z. B. > 2 sek. ist, dann wird die antwort wohl negativ sein. wie kann ich nun TCPConnect abbrechen?