TCP Verbindung in BEIDE RICHTUNGEN?

  • Hallo,
    Ich habe mit den TCP Funktionen von AutoIt eine TCP Verbindung von meinem PC zu meinem Laptop hergestellt.
    Der Laptop als Server und der PC als Client. (VORERST)
    Jetzt kann ich vom PC an den Laptop Daten senden. Das funktioniert auch.
    Ich sende jetzt einen Befehl an den Laptop der Informationen für eine MsgBox enthält. also titel,nachricht,timeout,icon
    Der Laptop teilt diesen string dann auf und zeigt mir ne Messagebox mit eben diesen Optionen.
    ABER: Jetzt will ich eine InputBox haben. Und ich will dass man dann eine Antwort an den PC zurücksenden kann.
    Und da hörts bei mir auf. Kein plan wie ich das anstellen soll.
    HILFE bitte.
    Muss ich da ne zweite Verbindung aufbauen? oder dieselbe mit derselben IP oder die IP vom PC? bin verzweifelt..

    Hier der quellcode vom PC (client):

    [autoit]

    TCPStartup()

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

    $socket=TCPConnect("192.168.0.101", 4600)

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

    $send=TCPSend($socket, "message|question|title|hello|5")

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

    While 1
    $socket_acp=TCPAccept($socket)
    $recv=TCPRecv($socket_acp, 1024)
    ?????????????????????????????????????????????
    WEnd

    TCPCloseSocket($socket_acp)
    TCPCloseSocket($socket)
    TCPShutdown()

    [/autoit]
  • TCPAccept() hat in einem Client nichts verloren. Diese Funktion wird nur im Server benötigt um neue eingehende Verbindungen von beliebigen Clients via TCPConnect() zu akzeptieren. Auch im Server solltest du darauf achten, dass du dir niemals eine TCPAccept() "socket" Variable mit einem schon verbundenen Client überschreibst, ansonsten kannst du nur noch mit dem neuverbundenen Client, aber nicht mehr mit dem alten Client kommunizieren. Wenn du also nur eine gleichzeitige Verbindung im Server zulassen willst darfst du TCPAccept() nach einer erfolgreichen Verbindung erst dann wieder aufrufen wenn die alte sauber beendet wurde. Alternativ kann und sollte man den oder die Verbindungssockets besser in einem Array speichern. So stellst du sicher, dass du jederzeit alle verbundenen Clients ansprechen kannst und die Verbindungen auch serverseitig beenden kannst.

    Soviel mal zu den Grundlagen wie man neue Verbindungen im Serverscript verarbeitet.

    Der Client muss kaum etwas tun. Er muss lediglich mit TCPconnect() eine Verbindung herstellen. Je nachdem wie du die Kommunikation zwischen Client und Server gestalten willst sendet nun der client mit TCPSend() seine Wünsche an den Server oder der Client wartet erstmal in einer Schleife mit TCPRecv() bis ihm der Server hallo sagt und ihm Instruktionen gibt. Die Verbindung zwischen beiden Scripten bleibt beliebig lange bestehen und es können beliebig oft von beiden Seiten aus Daten mit TCPSend() gesendet und mit TCPRecv() empfangen werden. Das einzige was du dafür brauchst ist im Client der socket den dir TCPconnect() zurückgibt und im Server der Socket den dir TCPAccept() zurückgibt.

    Dein Problem wird vermutlich zum einen wie oben angesprochen damit zusammenhängen, dass dein Server schon beim zweiten Schleifendurchlauf den Socket des Clients nicht mehr kennt und zum anderen natürlich dass dein Client am falschen Socket auf Nachrichten wartet. Dein Client ist in der jetzigen Form Server und Client gleichzeitig, wobei er als Client nur einmalig etwas sendet und keine Antwort vom Server abwartet. In der Endlosschleife wartet dein Client dann nur noch auf eingehende Verbindungen, sprich er ist nun ein Server.

    Ich hoffe du konntest mir folgen und hast verstanden was du falsch machst.

    2 Mal editiert, zuletzt von misterspeed (9. Januar 2015 um 19:37)

  • Danke erstmal für die Antwort,
    irgendwie versteh ichs ja. Aber irgendwie funktionierts nich :/ ???

    Hier der server script:

    [autoit]

    TCPStartup()

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

    Global $input="empty"
    $socket=TCPListen("192.168.0.101", 4600)

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

    While 1
    $connection=TCPAccept($socket)
    TCPSend($connection, "hello")
    WEnd

    [/autoit]

    und hier der client script:

    [autoit]

    TCPStartup()

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

    Global $var
    $socket=TCPConnect("192.168.0.101", 4600)

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

    While 1
    $var=TCPRecv($socket, 1024)
    MsgBox(0, "test", $var)
    WEnd

    [/autoit]

    Der server soll doch nur "hallo" senden. Aber das tut er nicht.
    Nur einmal kurz aber dann kommt gar nichts an.

  • Hey, schau dir mal mein Beispiel an:

    Spoiler anzeigen
    [autoit]

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +

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

    Global Const $sIPAddr = '127.0.0.1'
    Global Const $iPort = 65432

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

    Global $iSocketListen, $iSocketAccept, $iSocketConnect, $sRecv

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

    TCPStartup()

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

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +
    If Not $CmdLine[0] Then
    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +
    ; #########
    ; # Server

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

    $iSocketListen = TCPListen($sIPAddr, $iPort) ; Listen Socket für den Server

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

    Run(StringFormat('"%s" "%s" "%s"', @AutoItExe, @ScriptFullPath, 'start')) ; Client starten

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

    Do
    $iSocketAccept = TCPAccept($iSocketListen) ; Auf Client warten
    Until @error <> -1

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

    Do
    $sRecv &= TCPRecv($iSocketAccept, 1024) ; Daten vom Client empfangen
    Until @error And $sRecv

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

    TCPSend($iSocketAccept, 'Send to Client') ; Daten zum Client senden

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

    MsgBox(0x40000, 'From Client:', $sRecv) ; Daten ausgeben

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

    TCPCloseSocket($iSocketListen)
    TCPCloseSocket($iSocketAccept)

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

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +
    Else
    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +
    ; #########
    ; # Client

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

    $iSocketConnect = TCPConnect($sIPAddr, $iPort) ; Zum Server verbinden

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

    TCPSend($iSocketConnect, 'Send to Server') ; Daten zum Server senden

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

    Do
    $sRecv &= TCPRecv($iSocketConnect, 1024) ; Daten vom Server empfangen
    Until @error And $sRecv

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

    MsgBox(0x40000, 'From Server:', $sRecv) ; Daten ausgeben

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

    TCPCloseSocket($iSocketConnect)

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

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +
    EndIf

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

    TCPShutdown()

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

    ; ++++++++++ +++++++++ ++++++++ +++++++ ++++++ +++++ ++++ +++ ++ +

    [/autoit]
  • funktioniert nicht.

    Das kann doch nicht so schwer sein...

    WARUM geht das nich???

    Hat jemand bitte ein beispielscript für mich. ein client script. und ein server script. Ich will das auf 2 PC's testen! einer als server und einer als client.
    und nicht über 127.0.0.1....

  • Du scheinst nicht wirklich gelesen zu haben was ich dir zum Thema Verbindungsverwaltung im Server geschrieben habe.

    Dein Server macht folgendes:

    1. Neue Verbindung akzeptieren und den Verbindungssocket in der Variable $connection speichern.
    Problem:
    Du prüfst nichtmal ob sich überhaupt ein Client verbunden hat und versuchst munter "test" an einen vielleicht garnicht existenten Socket zu schicken. Schau dir bitte die Hilfe zu TCPAccept an, dort findest du z.B. die Info, dass die Funktion -1 zurückgibt wenn sich niemand verbunden hat (Fehlerfall), davon ab findest du dort auch ein passendes Code Beispiel.

    2. Nach deinem evtl. erfolglosen Versuch etwas an "Niemanden" zu schicken machst du genau das was ich dir in meinem ersten Posting schon geschrieben habe.
    Problem:
    Du überschreibst im zweiten Durchlauf der Schleife die Variable $connection das Senden klappt also im Höchstfall genau einmal, nämlich immer dann wenn dein Client sich gerade eben erst mit dem Server verbunden hat. Nach dem jeweils nächsten Schleifendurchlauf kennt dein Server den Client nicht mehr, da du den Socket überschreibst.

    Dein Client zeigt unter Umständen auch nicht zwingend beim ersten Mal den Text "test" an, da das tcprecv evtl. ausgeführt wird bevor dein Server die Nachricht gesendet hat. Deswegen kann die msgbox natürlich auch mal leer sein. Ich würde zum testen im übrigen entweder mit consolewrite() arbeiten oder eine kleine GUI verwenden in der du die empfangenen oder gesendeten Texte anzeigst. Eine msgbox ist blockierend, das bedeutet solange die msgbox angezeigt wird arbeitet das betreffende Script nicht weiter.

    Einmal editiert, zuletzt von misterspeed (9. Januar 2015 um 20:19)

  • @jbc:
    Natürlich funktioniert mein Beispiel! Ich veröffentliche nie ungetestete Skripte außer in bestimmten Ausnahmesituationen. Du hast hier von misterspeed gute Erklärungen erhalten was du falsch machst. Von mir hast du ein Beispielskript bekommen welches sowohl den Server wie auch den Client enthält. Es wird einmal vom Client zum Server und einmal vom Server zum Client eine Nachricht geschickt. Ich habe dir also genau ein Beispiel (passend zu den Erklärungen) zu deinem Problem geschrieben.

    Ließ dir am besten nochmal alles genau durch! Das Beispiel sollte dir dabei helfen.