Hardware Baukasten Tinkerforge

  • Hi

    Ich bin vor kurzem im Netz über Tinkerforge gestoßen.
    Nachdem ich kurz darüber nachgedacht hatte was man damit alles basteln kann,
    habe ich mit das kleinste Kit um erst einmal zu testen bestellt.
    Cool wäre dann mit euch zusammen Autoit und Tinkerforge zu verbinden -> UDF.

    Alter Beitrag weiter lesen...

    Spoiler anzeigen


    [Blockierte Grafik: https://shop.tinkerforge.com/media/catalog/product/cache/2/image/600x600/9df78eab33525d08d6e5fb8d27136e95/s/t/starter_kit_neu_600.jpg]
    Nachdem ich etwas Ärger beim Installieren der Treiber/Hardware hatte, konnte ich die ersten Spielereien
    über den mitgelieferten Brick Viewer testen.
    Falls da auch jemand dran hängt:

    Spoiler anzeigen


    - der Dienst "Deamon" muss vorhanden und gestartet sein
    - im Gerätemanager muss unter "libusb..." -> "Brick_Treiber" vorhanden sein
    - Brick Viewer starten. Sollte bei Connect kein Fehler kommen, aber keine Daten im Viewer auftauchen
    steckt
    das Dingen in nen anderen USB Slot. Bei mir hat es erst geklappt als
    ich einen passiven USB-Hub dazwischen geklemmt habe. Warum auch immer...


    Wenn ich das bis jetzt richtig verstanden habe wird beim Installieren ein Service gestartet,
    der als "Daemon" bezeichnet wird. Er verbinden die Kommunikation die eigentlich über das TCP/IP
    Protokoll läuft. D.h. angeschlossen werden die Komponenten via USB ( WLAN und LAN auch möglich durch Erweiterungen )
    und über den Deamon dann per localhost Port 4223 angesprochen.
    Das sieht im Viewer dann so aus:
    autoit.de/wcf/attachment/19092/

    Ich habe jetzt hier den Master Brick 2.0 und ein LCD Bricklet angeschlossen.
    Geht man jetzt auf den Tab LCD 20x4.. Kann man das LCD schon mit eigenen Eingaben füttern.
    autoit.de/wcf/attachment/19102/
    autoit.de/wcf/attachment/19097/

    Jetzt zu Autoit:
    Es gitb um TF anzusprechen einige Sprachen hier zu finden.
    Ich denke das zum Übersetzen und erstellen einer UDF am besten C++ als Vorlage sein sollte.
    Mein Problem ist nur das ich mich kaum/nicht mit C++ auskenne. Ich dachte das die PHP
    Schnittstelle mir mehr liegt. Ist aber auch leider etwas krass. Daher könnte ich für den Anfang vielleicht etwas
    Hilfe benötigen. Vielleicht hat ja auch der ein oder andere lust mit zu machen.

    Ich habe zum testen jetzt schon einmal folgendes ausprobiert.

    Spoiler anzeigen
    [autoit]

    $TF_ConnectIP = '127.0.0.1'
    $TF_Port = '4223'
    $TF_UID_DC = '6xicsa'

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

    TCPStartup()

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

    $TF_Socked = TCPConnect($TF_ConnectIP,$TF_Port)
    If $TF_Socked <> '' Then
    ConsoleWrite("Socked: "&$TF_Socked &@CRLF)
    EndIf

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

    Dim $aDataOld
    While 1
    Sleep(10)
    $aData = TCPRecv($TF_Socked, 2048 )
    If $aDataOld <> $aData And $aData <> '' Then
    ConsoleWrite("Data: "&$aData&@CRLF)
    $aDataOld = $aData
    EndIf
    WEnd

    [/autoit]


    Wenn ich jetzt im Viewer auf Connect drücke erhalte ich

    SQL
    Socked: 452
    Data:
     
    0x3134B8D822FD080036786963736100003000000000000000300200000200000D0000CC9D000022FD08006431750000000000367869637361000064010200020001D40000

    Da stehe ich jetzt schon etwas vor einem Berg. Ich habe auf der TF Seite auch schon etwas über das Protokoll gefunden.
    Wie gesagt vielleicht hat hier jemand schon ne Idee bzw. werde ich mich noch etwas durch die TF Seite und das Forum lesen.

    Würde mich mal interessieren was Ihr davon haltet und ob jemand mitmachen möchte.

    MFG chris

    Nach etwas längerer Zeit der Pause ;) bin ich auch weiter gekommen.
    Aber bitte beachten das ich noch kein @error Handling eingebaut habe.
    Aber jetzt zum Interessanten..

    Was bis jetzt funktioniert: ( nur ein ganz ganz kleiner Teil )
    - Autoit Anbindung über TCP/IP an den Daemon
    - 2D Array mit der Übersicht der angeschlossenen Brick und Bricklets
    - "Hallo Welt" Ausgabe mit Custom Char auf einem Bricklet LCD Display 20x4

    Bitte immer die aktuelle TF.au3 laden!
    ganz unten...

    Bsp. 1:

    Spoiler anzeigen
    [autoit]

    #include'TF.au3'

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

    Global $TF_BrickMaster_UID = _TF_UID_Convert('6xicsa'); = Base58 => 3635950641 = Uint32 => 3134B8D8
    Global $TF_BrickletLCD20x4_UID = _TF_UID_Convert('cd1'); = Base58 => 37700 = Uint32 => 44930000
    Global $_TF_Global_TCP_DEBUG = True

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

    Global $TFc = _TF_Startup('127.0.0.1','4223')
    If @error Then
    MsgBox(16,"error","Keine Verbindung zum Daemon")
    Exit
    EndIf

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

    $StackArray = _TF_Daemon_Get_StackData_2DArray($TFc)
    _ArrayDisplay($StackArray)

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

    _TF_BrickletLCD20x4_Clear_Display($TFc,$TF_BrickletLCD20x4_UID)
    _TF_BrickletLCD20x4_Backlight($TFc,$TF_BrickletLCD20x4_UID );Licht an

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

    Dim $TF_sCharArray[8]
    $TF_sCharArray[0]='10000'
    $TF_sCharArray[1]='11000'
    $TF_sCharArray[2]='11100'
    $TF_sCharArray[3]='11110'
    $TF_sCharArray[4]='11110'
    $TF_sCharArray[5]='11100'
    $TF_sCharArray[6]='11000'
    $TF_sCharArray[7]='10000'
    _TF_BrickletLCD20x4_Set_Custom_Character($TFc,$TF_BrickletLCD20x4_UID,0,$TF_sCharArray)

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

    _TF_BrickletLCD20x4_Write_Line($TFc,$TF_BrickletLCD20x4_UID,1,2,'\0 Hallo Welt !')

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

    Sleep ( 2500 )
    _TF_BrickletLCD20x4_Clear_Display($TFc,$TF_BrickletLCD20x4_UID)
    _TF_BrickletLCD20x4_Show_AllCustomChars($TFc,$TF_BrickletLCD20x4_UID)

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

    Sleep ( 2500 )

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

    _TF_BrickletLCD20x4_Backlight($TFc,$TF_BrickletLCD20x4_UID,0 );Licht aus
    _TF_BrickletLCD20x4_Clear_Display($TFc,$TF_BrickletLCD20x4_UID)

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


    Array Display:
    autoit.de/wcf/attachment/25007/

    Da die meinsten es nicht sehen können was auf dem Display passiert hier ein kleines Video:

    Youtube Video

    Bsp. 2:

    Spoiler anzeigen
    [autoit]

    #include'TF.au3'

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

    Global $TF_BrickMaster_UID = _TF_UID_Convert('6xicsa'); = Base58 => 3635950641 = Uint32 => 3134B8D8
    Global $TF_BrickletLCD20x4_UID = _TF_UID_Convert('cd1'); = Base58 => 37700 = Uint32 => 44930000
    Global $_TF_Global_TCP_DEBUG = False

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

    Global $TFc = _TF_Startup('127.0.0.1','4223')
    If @error Then
    MsgBox(16,"error","Keine Verbindung zum Daemon")
    Exit
    EndIf

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

    ; Display säubern und Licht an
    _TF_BrickletLCD20x4_Clear_Display($TFc,$TF_BrickletLCD20x4_UID)
    _TF_BrickletLCD20x4_Backlight($TFc,$TF_BrickletLCD20x4_UID );Licht an

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

    ; Sonderzeichen für Progressbar ins RAM Stelle \3-\7 vom Display schreiben
    _TF_BrickletLCD20x4_ProgressOn($TFc,$TF_BrickletLCD20x4_UID)

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

    ;Schleife
    For $i = 0 To 100

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

    ; Prozent im Display setzen wie in Autoit 1 = ( Zeile 1 Prozentzahl Zeile 2 Balken )
    _TF_BrickletLCD20x4_ProgressSet($TFc,$TF_BrickletLCD20x4_UID, $i, 1 )
    Sleep(100)

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

    Next

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

    ;Auf 100 Prozent setzen
    _TF_BrickletLCD20x4_ProgressSet($TFc,$TF_BrickletLCD20x4_UID, 100, 1 )

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

    Sleep(2000)

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

    ;Display säubern
    _TF_BrickletLCD20x4_Clear_Display($TFc,$TF_BrickletLCD20x4_UID)

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

    ;Smiley als Sonderzeichen ans RAM Stelle \0 des Displays
    Dim $TF_sCharArray[8]
    $TF_sCharArray[0]='00000'
    $TF_sCharArray[1]='01010'
    $TF_sCharArray[2]='01010'
    $TF_sCharArray[3]='01010'
    $TF_sCharArray[4]='00000'
    $TF_sCharArray[5]='10001'
    $TF_sCharArray[6]='01110'
    $TF_sCharArray[7]='00000'
    _TF_BrickletLCD20x4_Set_Custom_Character($TFc,$TF_BrickletLCD20x4_UID,0,$TF_sCharArray)

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

    ;Zeile ausgeben
    _TF_BrickletLCD20x4_write_line($TFc,$TF_BrickletLCD20x4_UID,2,4,'MFG Chris \0')

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

    Sleep(2000)
    _TF_BrickletLCD20x4_Clear_Display($TFc,$TF_BrickletLCD20x4_UID)
    _TF_BrickletLCD20x4_Backlight($TFc,$TF_BrickletLCD20x4_UID,0 )

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


    Damit Ihr wieder sehen können was auf dem Display passiert:

    Youtube Video

    Aktueller Stand ( 9 Beispiele :(

    In der angehangenen Zip ist die TF.au3 + Beispiele

    TinkerForge_Bsp1_LCDHelloWorld
    TinkerForge_Bsp2_LCDProgessBar
    TinkerForge_Bsp3_FirstEvent
    TinkerForge_Bsp4_GetStackData
    TinkerForge_Bsp5_Poti
    TinkerForge_Bsp10_1_ServoBrick
    TinkerForge_Bsp10_2_ServoBrick_Event
    TinkerForge_Bsp11_1_StepperBrick
    TinkerForge_Bsp12_16IO

    Aktuelle Version hier Runterladen 06.03.2015
    autoit.de/wcf/attachment/25232/

    Soooo... Wie gesagt das ist nur der Anfang...
    Aber ich hoffe es kann jemand gebrauchen bzw. hat lust es mit weiter aus zu bauen.
    Ich werde versuchen nach und nach alles zu übersetzen.

    Wenn jemand noch Ideen und weitere Anregungen hat immer raus damit!

    MFG Chris :D

  • Ich weiß, der Thread ist alt aber ich möchte da trotzdem keinen neuen aufmachen. Grundsätzlich würden mich Autoit Bindings auch interessieren. Um schnell mal eine GUI zu erstellen gibt es unter Windows einfach nichts besseres. Soweit ich weiß werden die Bindings bei TF automatisch aus Definitionen generiert. Vielleicht kommt man da irgendwie dran. Außerdem gibt es (inzwischen) auch direkt die Möglichkeit TCP zu benutzen. Ich denke da ist es besser sich von den anderen Bindings nur die Funktionsweise abzugucken und dann die TCP Doku Schritt für Schritt umzusetzen.

  • Hallo

    Ich bin jetzt an einem Punkt angekommen, an dem ich mir Gedanken machen muss wie ich Events von der Hardware, also TCP/IP Pakete abfange und verarbeiten muss,
    die nicht ein Resultat einer Abfrage sind. Z.B. Drücken einer der vier Tasten am LCD Display. D.H. sie können auch an einem zeitpunkt kommen in dem das Autoit Script gerade eine ganz andere Aufgabe erledigt.
    Damit würde dann das TCP/IP Paket ins leere laufen oder?
    In Tinkerforge sind das dann die Callback Funktionen.
    Jetzt die eigentliche Frage...

    1. Fange ich das ganze in einer While Schleife ab. In etwa so wie GuiGetMsg()...
    - Nachteil ist aber ganz klar das Pakete verloren gehen können

    Spoiler anzeigen
    [autoit]

    #include'TF.au3'

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

    Global $TF_BrickMaster_UID = _TF_UID_Convert('6xicsa'); = Base58 => 3635950641 = Uint32 => 3134B8D8
    Global $TF_BrickletLCD20x4_UID = _TF_UID_Convert('cd1'); = Base58 => 37700 = Uint32 => 44930000

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

    While 1
    $idMsg = _TF_GetMsg();Nur jetzt werdem Nachrichten angenommen
    Select
    Case $idMsg = $TF_BrickletLCD20x4_UID

    ; Weitere selektierung der Msg vom LCD Display

    Case $idMsg = $TF_BrickMaster_UID

    ; Weitere selektierung der Msg vom Master

    EndSelect
    WEnd

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

    2. Erledige ich das ganze wie GUIOnEventMode mit AdlibRegister?
    Vorteil, jetzt sollten keine Pakete mehr verlogen gehen?
    Nachteil, das Script wird in anderen Bereichen unterbrochen wenn ein Event von TF statt findet...

    Spoiler anzeigen
    [autoit]

    #include'TF.au3'

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

    Global $TF_BrickMaster_UID = _TF_UID_Convert('6xicsa'); = Base58 => 3635950641 = Uint32 => 3134B8D8
    Global $TF_BrickletLCD20x4_UID = _TF_UID_Convert('cd1'); = Base58 => 37700 = Uint32 => 44930000

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

    _TF_SetOnEvent($TFc,$TF_BrickletLCD20x4_UID,$EVENT_ID,"_FunktionTasteGedrueckt")
    _TF_SetOnEvent($TFc,$TF_BrickMaster_UID,$EVENT_ID,"_FunktionMainChipZuWarm")

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

    While 1
    Sleep(5)
    WEnd

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

    Func _FunktionTasteGedrueckt($Var1,$Var2,...)

    ; mach was ....

    EndFunc

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

    Func _FunktionMainChipZuWarm($Var1,$Var2,...)

    ; Kühl mich ;)

    EndFunc

    [/autoit]

    3. Kombination aus den beiden oben.
    Nach meiner Meinung das beste. Es sollten keine Pakete verloren gehen und der User kann entscheiden ob Event nach und nach im While abgearbeitet werden
    oder durch ein _TF_SetOnEvent() direkt mit Unterbrechung des restlichen Scripts

    Spoiler anzeigen
    [autoit]

    #include'TF.au3'

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

    Global $TF_BrickMaster_UID = _TF_UID_Convert('6xicsa'); = Base58 => 3635950641 = Uint32 => 3134B8D8
    Global $TF_BrickletLCD20x4_UID = _TF_UID_Convert('cd1'); = Base58 => 37700 = Uint32 => 44930000

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

    ; evtl. kommt der Buffer auch in _TF_Startup()
    _TF_EventBuffer() ; Buffer wird mit AdlibRegister gefüllt und in der While Schleife über _TF_GetMsg nach und nach abgerufen

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

    _TF_SetOnEvent($TFc,$TF_BrickletLCD20x4_UID,$EVENT_ID,"_FunktionTasteGedrueckt"); Wird direkt beim Event ausgeführt ohne GetMsg()

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

    While 1
    $idMsg = _TF_GetMsg()
    Select
    Case $idMsg = $TF_BrickletLCD20x4_UID

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

    ; Weitere selektierung der Msg vom LCD Display

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

    Case $idMsg = $TF_BrickMaster_UID

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

    ; Weitere selektierung der Msg vom Master

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

    EndSelect
    WEnd

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

    Func _FunktionTasteGedrueckt($Var1,$Var2,...)

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

    ; mach was ....

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

    EndFunc

    [/autoit]

    Jetzt bin ich mal gespannt was Ihr so denkt. Freue mich auf Feedback. Danke.

    MFG Chris :D

  • Hallo,
    Erstmal muss ich sagen das ich nicht am Rechner sitze und deswegen auch nichts nachschlagen kann.

    Aber ich arbeite auch öfters mit TCP Client-Server Scripten, und mir ist über TCP nie ein Paket verloren gegangen! Auch wenn was gesendet wird und ich erst später abfrage, erhalte ich immer die korrekten Daten! Ich habe deine UDF jetzt nicht durchgelesen und habe auch nicht diese Hardware - Kann deswegen nichts testen.
    Aber der TCP-Stack wird doch von Windows verwaltet und hat auch einen Cache-Speicherbereich! Sobald du mit einer TCP Funktion diesen ausließt wird er geleert. Du mußt nicht Syncron mit dieser Hardware arbeiten, wenn du es nicht willst ;)

    Hoffe ich konnte etwas helfen.
    Grüsse!

  • AutoIt liest nur den TCP-Puffer aus.
    Erst dann wird das nächste ACK zum Sender geschickt, so dass dieser wieder Daten (maximal die TCP Receive Window Size) sendet.

    Da geht nichts verloren....

    • Offizieller Beitrag

    Wie sieht denn so eine AutoIt Callback-Funktion aus?


    Hier mal ein ganz primitives Bsp., nicht unbedingt sinnvoll, aber es zeigt, wie Callbackfunktionen arbeiten.
    Eine Callbackfunktion ist eine Rückruf-Funktion.
    Sie wird einer anderen Funktion als Parameter mitgegeben und von dieser bei Vorliegen entsprechender Bedingungen aufgerufen.

    Spoiler anzeigen
    [autoit]

    $sTest = "AutoIt v3 is a freeware BASIC-like scripting language designed for automating the Windows GUI and general scripting."
    $sSearch = "designed"

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

    $ret = _SomeFunc($sTest, $sSearch, _MyCallback)
    ConsoleWrite('"' & $sSearch & '" ist Wort Nummer: ' & $ret & @CRLF)

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

    ; die Funktion durchsucht wortweise einen String nach einem Suchbegriff. Bedingung zum Aufruf der Callbackfunktion ist, dass das zu prüfende Wort mehr als 5 Buchstaben hat.
    ; Zurückgegeben wird, das wievielte Wort der Suchbegriff ist, bei nicht finden '0'.
    Func _SomeFunc($sStr, $sFind, $cb_func)
    Local $iLen, $aWords = StringSplit($sStr, ' ')
    For $i = 1 To $aWords[0]
    $iLen = StringLen($aWords[$i])
    If $iLen > 5 And $cb_func($aWords[$i], $sFind) Then Return $i
    Next
    Return 0
    EndFunc

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

    ; Die Callback-Funktion beeinflusst die aufrufende Funktion. Bei Erreichen einer Bedingung wird die aufrufende Funktion vorzeitig beendet.
    ; Dabei ist die Callback-Funktion neutral, da sie in der Deklaration selbst nicht weiß, worauf sie reagiert. Diese Angaben erhält sie erst durch die Aufruf-Funktion.
    Func _MyCallback($sParam, $sCheckVal)
    Local $fRet = False
    If $sParam = $sCheckVal Then $fRet = True
    Return $fRet
    EndFunc

    [/autoit]
  • Hey BugFix

    Danke für die lehrreiche Stunde :thumbup: . Wie immer mal wieder was dazu gelernt.
    Wenn dem so ist, habe ich den Begriff "CallBack" in der Hinsicht bis jetzt falsch interpretiert.
    Daher weiß ich jetzt, das es nicht das ist was ich suche / brauche.

    Das was ich brauche ist dann eher doch was in Richtung GUIRegisterMsg()
    Es geht ja darum wenn eine Antwort von Tinkerforge mittels TCP kommt, das dann eine Funktion ausgelöst wird.
    Die Idee ist es hier hin zu kommen...

    Spoiler anzeigen
    [autoit]

    _TF_EventMode(True); Ab jetzt werden Funktionen Automatisch aufgerufen Wenn ein Event von TF mittels TCP kommt
    _TF_SetOnEvent_BrickletLCD20x4_Button0_Pressed($TF_BrickletLCD20x4_UID,'_MeineLCDButtonFunktion_Button0'); Wenn man den Taster am Dispay drückt, dann Funktion '_MeineLCDButtonFunktion_Button0' aufrufen

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

    While 1
    Sleep(10)
    WEnd

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

    Func _MeineLCDButtonFunktion_Button0()
    _TF_BrickletLCD20x4_Backlight($TFc,$TF_BrickletLCD20x4_UID ); Hintergrundlich des Displays einschalten

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

    EndFunc

    [/autoit]


    Wie realisiere ich so etwas?

    Edit: Mit AdlibRegister() habe ich schon getestet, aber das läuft irgendwie unrund...
    Edit2: Gefunden habe ich das hier bis jetzt... http://www.autoitscript.com/forum/topic/35389-tcp-event-mode/

    Wie immer vielen Dank schon einmal für eine Antwort...

    MFG Chris :D

    • Offizieller Beitrag

    Das was ich brauche ist dann eher doch was in Richtung GUIRegisterMsg()
    Es geht ja darum wenn eine Antwort von Tinkerforge mittels TCP kommt, das dann eine Funktion ausgelöst wird.


    Nun, genau das ist eigentlich der Sinn von Callbacks.
    Du denkst an ein Polling (AdlibRegister oder Ähnliches) um zu Prüfen, ob eine Nachricht vorhanden ist. Das übernimmt doch die Callback-Funktion. Das Auslöseereignis zum Start der Funktion ist, dass Nachrichten auflaufen.
    Mal grob skizziert:
    - Endlosschleife
    - TCPRecv wartet auf Input
    - wird etwas empfangen, sammelst du den Eingang (falls mehr als das ausgehandelte Limit übertragen wird)
    - zum Ende der aktuellen Sendung liefert TCPRecv @error
    - jetzt kannst du die empfangenen Daten zur Verarbeitung an die Callback-Funktion übergeben
    - hinterher kehrst du aus dieser Funktion wieder in die Endlosschleife zurück um auf weitere Sendungen zu warten

    Probier mal, ob du das hinbekommst. Danach hast du das Prinzip auch sicher verstanden und nie wieder Probleme damit ;)


    EDIT: Oops, jetzt hatte ich deinen Spoiler gar nicht gelesen - ich schaue es mir nochmal genauer an.

  • Hey..

    EDIT: Oops, jetzt hatte ich deinen Spoiler gar nicht gelesen - ich schaue es mir nochmal genauer an.

    Ja jetzt glaube ich hast du mich verstanden ;)
    Da das ganze ja eine UDF werden soll möchte ich den Nuter der UDF ja nicht damit beschäftigen das er danach schaut ob ein Aktion von TF anliegt.
    Es muss ja auch nicht immer eine Antwort auf eine Abfrage der UDF sein. Es kann ja auch ein Tastendruck eines Tasters von TF sein.

    Der Beitrag auf http://www.autoitscript.com/forum/topic/74…f-event-driven/ kommt dem ganzen schon recht nahe.
    Aber leider sehr verstrickt. Das muss man doch irgendwie smarter lösen können.
    Es müsste ja nur eine Buffer() Funktion ausgelöst werden sobald ein TCP Paket rein kommt..das würde mir reichen...
    Sowas wie

    [autoit]

    TcpRecvEvent($Conn,"_DeineFunktion")

    [/autoit]

    Ich habe mit der UDF aus dem Englischen Forum etwas rumgespielt und es hinbekommen das sogar wenn das eigentliche Programm an einer MsgBox wartet,
    die Funktion durch ein TCP Paket aufgerufen wird. Aber dann funktioniert der Rest meiner UDF nicht mehr, da der Socked da irgendwie anders aufgebaut wird. Mit DLLs oder so...

    MFG Chris :D

    • Offizieller Beitrag

    Also ich kann leider nichts konkretes zu deinem Problem beitragen. Das Problem ist, dass ich das komplett im Kopf durchspielen muss ohne das System zu kennen und ohne testen zu können. Und erst die Doku lesen ist mir dann jetzt doch etwas to much.

  • Hi..

    Nein das ist richtig... wäre viel zu aufwändig.. aber das brauchst du ja auch überhaupt nicht.
    Im Prinzip hat das was ich brauche und mein Problem ist, ja auch nicht mehr mit Tinkerforge zu tun.
    Wir brauchen nur einen Weg eine TcpOnRecvEvent Funktion, die auf das normale TCPConnect() aufsattelt zu bauen.
    Den Rest mache ich alleine...

    Ich hab mal etwas getestet...
    Das hier ist der Test-Dummy der TF ersetzt und einfach eine TCP Conn aufbaut und ein Datenpaket verschickt

    Spoiler anzeigen
    [autoit]


    TCPStartup()
    $hConn = TCPConnect('127.0.0.1',4222)
    If @error Then
    MsgBox(16,@error,"TCP Connect Error")
    Exit
    EndIf

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

    TCPSend($hConn,@HOUR&':'&@SEC)
    If @error Then
    MsgBox(16,@error,"TCP Send Error")
    Exit
    EndIf

    [/autoit]


    Den am besten compilieren weil man nicht zwei Scripts gleichzeitig laufen lassen kann. ( Oder ich nur nicht weiß das das in Scite geht ;) )
    Wenn man jetzt das zweite Script startet... und dann den Dummy startet...

    Spoiler anzeigen
    [autoit]

    Global Const $FD_READ = 1
    Global Const $FD_WRITE = 2
    Global Const $FD_OOB = 4
    Global Const $FD_ACCEPT = 8
    Global Const $FD_CONNECT = 16
    Global Const $FD_CLOSE = 32
    Global $hWs2_32 = -1

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

    Global Const $TCP_SEND = 1
    Global Const $TCP_RECEIVE = 2
    Global Const $TCP_CONNECT = 4
    Global Const $TCP_DISCONNECT = 8
    Global Const $TCP_NEWCLIENT = 16

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

    TCPStartup()
    Global Const $__TCP_WINDOW = GUICreate("Async Sockets UDF")
    Global $__TCP_SOCKETS[1][7]

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

    $hServer = _TCP_Server_Create(4222,'127.0.0.1')
    _TCP_RegisterEvent($hServer, $TCP_RECEIVE, "Buffer")

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

    While 1
    Sleep(5)
    ;~ MsgBox(0,"",55 )
    ;~ Exit
    WEnd

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

    Func Buffer($hSocket,$aData,$error)
    Call("Event",$aData)
    EndFunc

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

    Func Event($aData)
    MsgBox(0,0,$aData )
    Exit
    EndFunc

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

    ;##################################################################################################

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

    Func _TCP_Server_Create($iPort, $sIP="0.0.0.0")

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

    Local $hListenSocket = ___ASocket()
    ___ASockSelect( $hListenSocket, $__TCP_WINDOW, 0x0400, $FD_ACCEPT)
    GUIRegisterMsg( 0x0400, "___TCP_OnAccept" )
    ___ASockListen( $hListenSocket, $sIP, $iPort )
    $__TCP_SOCKETS[0][0] = $hListenSocket
    $__TCP_SOCKETS[0][1] = 0x0400
    Return $hListenSocket

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

    EndFunc

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

    Func ___TCP_OnAccept($hWnd, $iMsgID, $WParam, $LParam)

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

    Local $hSocket = $WParam
    Local $iError = ___HiWord( $LParam )
    Local $iEvent = ___LoWord( $LParam )
    Local $hClient, $uBound

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

    Abs($hWnd) ; Stupid AU3Check...

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

    If $iMsgID = $__TCP_SOCKETS[0][1] Then

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

    If $iEvent = $FD_ACCEPT Then

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

    If Not $iError Then

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

    ReDim $__TCP_SOCKETS[UBound($__TCP_SOCKETS)+1][7]
    $uBound = UBound($__TCP_SOCKETS)

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

    $hClient = TCPAccept($hSocket)

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

    ___ASockSelect($hClient, $__TCP_WINDOW, 0x0400 + $uBound - 1, BitOR($FD_READ, $FD_WRITE, $FD_CLOSE))
    GUIRegisterMsg(0x0400 + $uBound - 1, "___TCP_Server_OnSocketEvent" )

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

    $__TCP_SOCKETS[UBound($__TCP_SOCKETS)-1][0] = $hClient
    $__TCP_SOCKETS[UBound($__TCP_SOCKETS)-1][1] = 0x0400 + $uBound - 1

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

    Call($__TCP_SOCKETS[0][6], $hClient, $iError)

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

    Else

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

    Call($__TCP_SOCKETS[0][6], 0, $iError)

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

    EndIf

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

    ElseIf $iEvent = $FD_CONNECT Then

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

    Call($__TCP_SOCKETS[0][4], $hSocket, $iError)

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

    EndIf

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

    EndIf

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

    EndFunc

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

    Func ___TCP_Server_OnSocketEvent( $hWnd, $iMsgID, $WParam, $LParam )

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

    Local $hSocket = $WParam
    Local $iError = ___HiWord( $LParam )
    Local $iEvent = ___LoWord( $LParam )

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

    Local $sDataBuff, $iElement, $i

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

    Abs($hWnd)

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

    $hSocket = 0
    $iElement = 0

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

    For $i = 1 to UBound($__TCP_SOCKETS)-1

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

    If $__TCP_SOCKETS[$i][1] = $iMsgID Then
    $hSocket = $__TCP_SOCKETS[$i][0]
    $iElement = $i
    ExitLoop
    EndIf

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

    Next

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

    If $hSocket Then

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

    Switch $iEvent
    Case $FD_READ

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

    $sDataBuff = TCPRecv($hSocket, 1024)

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

    Call($__TCP_SOCKETS[0][2], $hSocket, $sDataBuff, $iError)

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

    Case $FD_WRITE

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

    Call($__TCP_SOCKETS[0][3], $hSocket, $iError)

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

    Case $FD_CLOSE

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

    ___ASockShutdown($hSocket)
    TCPCloseSocket($hSocket)

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

    Call($__TCP_SOCKETS[0][5], $hSocket, $iError)

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

    ___ArrayDelete($__TCP_SOCKETS, $iElement)

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

    EndSwitch

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

    EndIf

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

    EndFunc

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

    Func _TCP_RegisterEvent($hSocket, $iEvent, $sFunction)

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

    Local $iSelected = 0
    Local $i

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

    If $__TCP_SOCKETS[0][0] Then

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

    $iSelected = 0

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

    Else

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

    For $i = 0 to UBound($__TCP_SOCKETS)-1
    If $__TCP_SOCKETS[$i][0] = $hSocket Then
    $iSelected = $i
    ExitLoop
    EndIf
    Next

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

    If Not $iSelected Then Return 0

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

    EndIf

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

    Switch $iEvent
    Case $TCP_SEND
    $__TCP_SOCKETS[$iSelected][3] = $sFunction
    Case $TCP_RECEIVE
    $__TCP_SOCKETS[$iSelected][2] = $sFunction
    Case $TCP_CONNECT
    $__TCP_SOCKETS[$iSelected][4] = $sFunction
    Case $TCP_DISCONNECT
    $__TCP_SOCKETS[$iSelected][5] = $sFunction
    Case $TCP_NEWCLIENT
    $__TCP_SOCKETS[$iSelected][6] = $sFunction
    Case Else
    Return False
    EndSwitch

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

    Return True

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

    EndFunc

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

    ;==================================================================================================================
    ;
    ; Zatorg's Asynchronous Sockets UDF Starts from here.
    ;
    ;==================================================================================================================

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

    Func ___ASocket($iAddressFamily = 2, $iType = 1, $iProtocol = 6)
    If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )
    Local $hSocket = DllCall($hWs2_32, "uint", "socket", "int", $iAddressFamily, "int", $iType, "int", $iProtocol)
    If @error Then
    SetError(1, @error)
    Return -1
    EndIf
    If $hSocket[ 0 ] = -1 Then
    SetError(2, ___WSAGetLastError())
    Return -1
    EndIf
    Return $hSocket[ 0 ]
    EndFunc ;==>_ASocket

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

    Func ___ASockShutdown($hSocket)
    If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )
    Local $iRet = DllCall($hWs2_32, "int", "shutdown", "uint", $hSocket, "int", 2)
    If @error Then
    SetError(1, @error)
    Return False
    EndIf
    If $iRet[ 0 ] <> 0 Then
    SetError(2, ___WSAGetLastError())
    Return False
    EndIf
    Return True
    EndFunc ;==>_ASockShutdown

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

    Func ___ASockClose($hSocket)
    If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )
    Local $iRet = DllCall($hWs2_32, "int", "closesocket", "uint", $hSocket)
    If @error Then
    SetError(1, @error)
    Return False
    EndIf
    If $iRet[ 0 ] <> 0 Then
    SetError(2, ___WSAGetLastError())
    Return False
    EndIf
    Return True
    EndFunc ;==>_ASockClose

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

    Func ___ASockSelect($hSocket, $hWnd, $uiMsg, $iEvent)
    If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )
    Local $iRet = DllCall( _
    $hWs2_32, _
    "int", "WSAAsyncSelect", _
    "uint", $hSocket, _
    "hwnd", $hWnd, _
    "uint", $uiMsg, _
    "int", $iEvent _
    )
    If @error Then
    SetError(1, @error)
    Return False
    EndIf
    If $iRet[ 0 ] <> 0 Then
    SetError(2, ___WSAGetLastError())
    Return False
    EndIf
    Return True
    EndFunc ;==>_ASockSelect

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

    ; Note: you can see that $iMaxPending is set to 5 by default.
    ; IT DOES NOT MEAN THAT DEFAULT = 5 PENDING CONNECTIONS
    ; 5 == SOMAXCONN, so don't worry be happy
    Func ___ASockListen($hSocket, $sIP, $uiPort, $iMaxPending = 5); 5 == SOMAXCONN => No need to change it.
    Local $iRet
    Local $stAddress

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

    If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )

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

    $stAddress = ___SockAddr($sIP, $uiPort)
    If @error Then
    SetError(@error, @extended)
    Return False
    EndIf

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

    $iRet = DllCall($hWs2_32, "int", "bind", "uint", $hSocket, "ptr", DllStructGetPtr($stAddress), "int", DllStructGetSize($stAddress))
    If @error Then
    SetError(3, @error)
    Return False
    EndIf
    If $iRet[ 0 ] <> 0 Then
    $stAddress = 0; Deallocate
    SetError(4, ___WSAGetLastError())
    Return False
    EndIf

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

    $iRet = DllCall($hWs2_32, "int", "listen", "uint", $hSocket, "int", $iMaxPending)
    If @error Then
    SetError(5, @error)
    Return False
    EndIf
    If $iRet[ 0 ] <> 0 Then
    $stAddress = 0; Deallocate
    SetError(6, ___WSAGetLastError())
    Return False
    EndIf

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

    Return True
    EndFunc ;==>_ASockListen

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

    Func ___ASockConnect($hSocket, $sIP, $uiPort)
    Local $iRet
    Local $stAddress

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

    If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )

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

    $stAddress = ___SockAddr($sIP, $uiPort)
    If @error Then
    SetError(@error, @extended)
    Return False
    EndIf

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

    $iRet = DllCall($hWs2_32, "int", "connect", "uint", $hSocket, "ptr", DllStructGetPtr($stAddress), "int", DllStructGetSize($stAddress))
    If @error Then
    SetError(3, @error)
    Return False
    EndIf

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

    $iRet = ___WSAGetLastError()
    If $iRet = 10035 Then; WSAEWOULDBLOCK
    Return True; Asynchronous connect attempt has been started.
    EndIf
    SetExtended(1); Connected immediately
    Return True
    EndFunc ;==>_ASockConnect

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

    ; A wrapper function to ease all the pain in creating and filling the sockaddr struct
    Func ___SockAddr($sIP, $iPort, $iAddressFamily = 2)
    Local $iRet
    Local $stAddress

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

    If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )

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

    $stAddress = DllStructCreate("short; ushort; uint; char[8]")
    If @error Then
    SetError(1, @error)
    Return False
    EndIf

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

    DllStructSetData($stAddress, 1, $iAddressFamily)
    $iRet = DllCall($hWs2_32, "ushort", "htons", "ushort", $iPort)
    DllStructSetData($stAddress, 2, $iRet[ 0 ])
    $iRet = DllCall($hWs2_32, "uint", "inet_addr", "str", $sIP)
    If $iRet[ 0 ] = 0xffffffff Then; INADDR_NONE
    $stAddress = 0; Deallocate
    SetError(2, ___WSAGetLastError())
    Return False
    EndIf
    DllStructSetData($stAddress, 3, $iRet[ 0 ])

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

    Return $stAddress
    EndFunc ;==>__SockAddr

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

    Func ___WSAGetLastError()
    If $hWs2_32 = -1 Then $hWs2_32 = DllOpen( "Ws2_32.dll" )
    Local $iRet = DllCall($hWs2_32, "int", "WSAGetLastError")
    If @error Then
    ;ConsoleWrite("+> _WSAGetLastError(): WSAGetLastError() failed. Script line number: " & @ScriptLineNumber & @CRLF)
    SetExtended(1)
    Return 0
    EndIf
    Return $iRet[ 0 ]
    EndFunc ;==>_WSAGetLastError

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

    ; Got these here:
    ; http://www.autoitscript.com/forum/index.ph…620&hl=MAKELONG
    Func ___MakeLong($LoWord, $HiWord)
    Return BitOR($HiWord * 0x10000, BitAND($LoWord, 0xFFFF)); Thanks Larry
    EndFunc ;==>_MakeLong

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

    Func ___HiWord($Long)
    Return BitShift($Long, 16); Thanks Valik
    EndFunc ;==>_HiWord

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

    Func ___LoWord($Long)
    Return BitAND($Long, 0xFFFF); Thanks Valik
    EndFunc ;==>_LoWord

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

    ; ========================================= Array functions

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ArrayDelete
    ; Description ...: Deletes the specified element from the given array.
    ; Syntax.........: _ArrayDelete(ByRef $avArray, $iElement)
    ; Parameters ....: $avArray - Array to modify
    ; $iElement - Element to delete
    ; Return values .: Success - New size of the array
    ; Failure - 0, sets @error to:
    ; |1 - $avArray is not an array
    ; |3 - $avArray has too many dimensions (only up to 2D supported)
    ; |(2 - Deprecated error code)
    ; Author ........: Cephas <cephas at clergy dot net>
    ; Modified.......: Jos van der Zande <jdeb at autoitscript dot com> - array passed ByRef, Ultima - 2D arrays supported, reworked function (no longer needs temporary array; faster when deleting from end)
    ; Remarks .......: If the array has one element left (or one row for 2D arrays), it will be set to "" after _ArrayDelete() is used on it.
    ; Related .......: _ArrayAdd, _ArrayInsert, _ArrayPop, _ArrayPush
    ; Link ..........;
    ; Example .......; Yes
    ; ===============================================================================================================================
    Func ___ArrayDelete(ByRef $avArray, $iElement)
    If Not IsArray($avArray) Then Return SetError(1, 0, 0)

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

    Local $iUBound = UBound($avArray, 1) - 1

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

    If Not $iUBound Then
    $avArray = ""
    Return 0
    EndIf

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

    ; Bounds checking
    If $iElement < 0 Then $iElement = 0
    If $iElement > $iUBound Then $iElement = $iUBound

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

    ; Move items after $iElement up by 1
    Switch UBound($avArray, 0)
    Case 1
    For $i = $iElement To $iUBound - 1
    $avArray[$i] = $avArray[$i + 1]
    Next
    ReDim $avArray[$iUBound]
    Case 2
    Local $iSubMax = UBound($avArray, 2) - 1
    For $i = $iElement To $iUBound - 1
    For $j = 0 To $iSubMax
    $avArray[$i][$j] = $avArray[$i + 1][$j]
    Next
    Next
    ReDim $avArray[$iUBound][$iSubMax + 1]
    Case Else
    Return SetError(3, 0, 0)
    EndSwitch

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

    Return $iUBound
    EndFunc ;==>_ArrayDelete

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


    passiert genau das was ich brauche. Eine Anfrage über TCP wird anscheinend über GUIRegisterMsg() und einen Dummy Gui abgefangen und daher als Event ausgegeben.
    Anscheinend wird aber hier irgendwas anders gemacht als das Hauseigene TCP von Autoit. Dahinter muss ich noch kommen und am besten auch wie das ganze klappt und wie ich das etwas smarter in die UDF einbauen kann...

    Naja ich teste mal weiter...
    Wenn jemand anderes noch was weiß immer raus damit ...

    EDIT: Was bedeutet z.B. GUIRegisterMsg( 0x0400, "___TCP_OnAccept" ). Also was bringt hier die 0x0400

    MFG Chris :D

  • Anscheinend wird aber hier irgendwas anders gemacht als das Hauseigene TCP von Autoit

    Da wird nichts anders gemacht...
    https://msdn.microsoft.com/de-de/library/…6(v=vs.85).aspx bzw.
    https://msdn.microsoft.com/de-de/library/…0(v=vs.85).aspx
    meldet bspw. das FD_READ (also das "es-kann-jetzt-etwas-aus-dem-Puffer-gelesen-werden"-Event) an ein Dummy-Fenster.
    Daraufhin wird per TCPRecv der Puffer ausgelesen. Der Rest ist Array-Gedöns aufgrund des "Multi"-TCP-Ansatzes (mehrere gleichzeitige Verbindungen)
    Wenn du nur eine Verbindung "überwachen" willst, ist das in ~10 Zeilen erledigt.

  • Hey Andy

    Danke für die Hilfe...
    Ich konnte jetzt etwas weiter kommen. Zumindestens wird das Event jetzt 1x aufgerufen.
    Aber leider nicht öfters... Wo könnte mein Fehler liegen?

    Hier der Dummy der die Daten sendet..

    Spoiler anzeigen
    [autoit]


    TCPStartup()
    $hConn = TCPConnect('127.0.0.1',4222)
    If @error Then
    MsgBox(16,@error,"TCP Connect Error")
    Exit
    EndIf

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

    $i = 0
    Do

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

    $i += 1
    ToolTip("Sende Msg "&$i)
    Sleep ( 1000 )
    TCPSend($hConn,@HOUR&':'&@MIN&':'&@SEC)
    If @error Then
    MsgBox(16,@error,"TCP Send Error")
    Exit
    EndIf

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

    Until $i > 40

    [/autoit]

    und hier der Empfang mit der Event Func

    Spoiler anzeigen
    [autoit]

    Global Const $FD_READ = 1
    Global Const $FD_WRITE = 2
    Global Const $FD_OOB = 4
    Global Const $FD_ACCEPT = 8
    Global Const $FD_CONNECT = 16
    Global Const $FD_CLOSE = 32
    Global $hWs2_32 = -1

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

    TCPStartup()
    $iListenSocket = TCPListen ( '127.0.0.1', 4222 )

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

    Do
    $iSocket = TCPAccept($iListenSocket)
    Until $iSocket <> -1
    TCPCloseSocket($iListenSocket)

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

    $__TCP_WINDOW = GUICreate("GUIRegisterMsg")
    $hWs2_32 = DllOpen( "Ws2_32.dll" )
    DllCall( $hWs2_32,"int", "WSAAsyncSelect", "uint", $iSocket, "hwnd", $__TCP_WINDOW, "uint", 0x0400, "int", $FD_WRITE )
    GUIRegisterMsg( 0x0400, "Event" )

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

    While 1
    Sleep(5)
    WEnd

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

    Func Event($hWnd, $iMsgID, $WParam, $LParam)
    $sDataBuff = TCPRecv($iSocket, 1024)
    MsgBox(0,"",$sDataBuff)
    EndFunc

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

    Danke schonmal...

    MFG Chris :D

  • Hi,

    so funktioniert das jedenfalls bei mir

    Spoiler anzeigen
    [autoit]

    Global Const $FD_READ = 1
    Global Const $FD_WRITE = 2
    Global Const $FD_OOB = 4
    Global Const $FD_ACCEPT = 8
    Global Const $FD_CONNECT = 16
    Global Const $FD_CLOSE = 32
    Global $hWs2_32 = -1

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

    TCPStartup()
    $iListenSocket = TCPListen ( '127.0.0.1', 4222 )

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

    Do
    $iSocket = TCPAccept($iListenSocket)
    Until $iSocket <> -1
    TCPCloseSocket($iListenSocket)

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

    $__TCP_WINDOW = GUICreate("GUIRegisterMsg")
    $hWs2_32 = DllOpen( "Ws2_32.dll" )
    DllCall( $hWs2_32,"int", "WSAAsyncSelect", "uint", $iSocket, "hwnd", $__TCP_WINDOW, "uint", 0x0400, "int", $FD_READ )
    GUIRegisterMsg( 0x0400, "Event" )

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

    While 1
    Sleep(5)
    WEnd

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

    Func Event($hWnd, $iMsgID, $WParam, $LParam)
    $sDataBuff = TCPRecv($iSocket, 1024)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sDataBuff = ' & $sDataBuff & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    MsgBox(0,"",$sDataBuff,1)
    DllCall( $hWs2_32,"int", "WSAAsyncSelect", "uint", $iSocket, "hwnd", $__TCP_WINDOW, "uint", 0x0400, "int", $FD_READ )
    EndFunc

    [/autoit]


    Keinesfalls darfst du Events blocken!
    Schon die Msgbox mit einer Sekunde delay ist grenzwertig.
    Weiterhin wartet der Receiver natürlich nur auf READ-Events. Zzt. bekommt er nichts davon mit, dass bspw. der Sender die Verbindung beendet hat!
    Das ist die Hausaufgabe fürs Wochenende ;)