Einfache TCP Socket Frage

  • Hallo Forum,

    ich würde gerne einen einfachen TCP Socket in Autoit erstellen, der die ganze Zeit auf meinem PC auf einem Port läuft.

    Wenn sich ein Gerät (egal was) verbindet, soll der Socket das erkennen.
    Wenn jetzt Daten von dem Gerät an den Socket gesendet werden, möchte ich diese in einer einfachen MsgBox für den Anfang ausgeben.

    Ich habe es auch schon soweit geschafft das ich beim einwählen meines Gerätes die MsgBox bekomme, und wenn ich dann einmalig Daten Sende, dann bekomme ich diese auch ausgegeben.
    Aber eben funktioniert das leider nur einmal. Danach muss ich den Socket neu starten.

    Könnt Ihr mir helfen zu verstehen warum das nicht funktioniert und nur einmal Daten annimmt und ausgibt?

    Danke EUCH, bzw. DIR !

    Hier mein kleines Socket Script:

    [autoit]


    TCPStartup() ; TCP wird initialisiert

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

    $mainsocket = TCPListen("192.168.178.49", 11111) ; Den mainsocket erstellen

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

    Do ; Solange ausführen bis sich ein Gerät verbindet
    $acceptedSocket = TCPAccept($mainsocket) ; Wir versuchen eine möglicher Verbindung anzunehmen

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

    Until $acceptedSocket <> -1

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

    MsgBox(0,"","Eine Verbindung wurde hergestellt") ; Hier hat ein Gerät eine Anfrage gesendet

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

    while 1

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

    $receivedData = TCPRecv($acceptedSocket, 1024) ; Wenn eine Socketverbindung hergestellt wurde, empfange ein Paket vom Client ($connectedSocket)

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

    if $receivedData <> "" then ;Wenn Daten vorhanden sind, dann gebe die Msgbox aus...
    MsgBox(64, "Nachricht empfangen!", "Es wurde eine Nachricht empfangen: " & $receivedData)
    EndIf

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

    WEnd

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

    TCPCloseSocket($acceptedSocket)

    [/autoit]
  • Hier in unserem Forum wurde diese Frage schon mindestens 1000000000000000000000000 Mal gestellt. ;)
    So funktioniert es:

    [autoit]

    TCPStartup()
    $hMainSocket = TCPListen("192.168.178.49", 11111)

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

    While 1
    MsgBox(0, "", "Ich warte auf eine neue Verbinung!")
    Do
    $hClientSocket = TCPAccept($hMainSocket)
    Until $hClientSocket <> -1
    MsgBox(0, "", "Eine Verbindung wurde hergestellt!")
    While 1
    $sReceivedData = TCPRecv($hClientSocket, 1024) ; Wenn eine Socketverbindung hergestellt wurde, empfange ein Paket vom Client ($connectedSocket)
    If @error Then
    ExitLoop
    ElseIf $sReceivedData <> "" Then
    MsgBox(64, "Nachricht empfangen!", "Es wurde eine Nachricht empfangen: " & $sReceivedData)
    EndIf
    WEnd
    TCPCloseSocket($hClientSocket)
    MsgBox(64, "", "Der Client hat die Verbinung getrennt!")
    WEnd

    [/autoit]

    :thumbdown:

    LG
    Christoph :)

  • Heißt das, das ich nach jedem Datensatz den ich empfangen habe die Verbindung trennen muss über TCPCloseSocket ?
    Und dann wieder neu beginnen muss ?


    Nein, das stimmt so nicht. Die Verbindung wird nur getrennt, wenn der Client die Verbindung unterbrochen hat.
    Dann wird nämlich von der Funktion TCPRecv @error gesetzt und die While-Schleife beendet:

    [autoit]

    While 1
    $sReceivedData = TCPRecv($hClientSocket, 1024) ; Wenn eine Socketverbindung hergestellt wurde, empfange ein Paket vom Client ($connectedSocket)
    If @error Then
    ExitLoop ; ---> Hier wird die Schleife beendet falls die Verbindung beendet ist (sonst läuft die Schleife immer weiter)
    ElseIf $sReceivedData <> "" Then
    MsgBox(64, "Nachricht empfangen!", "Es wurde eine Nachricht empfangen: " & $sReceivedData)
    EndIf
    WEnd

    [/autoit]

    Ansonsten wird der gesendete Text ausgegeben (sofern etwas gesendet wurde) und dann werden wieder per TCPRecv die Daten empfangen.
    (Die Schleife beginnt von vorn und die Verbindung wurde nicht getrennt.)

    MfG Xenon

  • tcpaccept erlaubt eine neue Verbindung, sobald sich ein client mit deinem Server erfolgreich verbunden hat kann er Daten senden, welche du dann mit tcprecv empfangen kannst. Wenn der Client nach dem Senden die Verbindung trennt, dann wars das und du erhälst nur noch ein @error bei tcprecv, weil der Socket nicht mehr existent ist. Verlierst du also aus welchem Grund auch immer die Verbindung zum Client, dann muss der Client sich neu verbinden und neue Verbindungen nimmt dein Server nur dann an, wenn du tcpaccept aufrufst (dein Fehler, da du das nur einmalig zum Script start machst). Somit konnte dien Script nur einmal funktionieren, nämlich genau solange wie die Verbindung bestand.

  • Danke euch beiden.

    Um mal etwas spezieller zu werden.
    Die Daten sende ich von meinem Handy aus. Das bedeutet, ich verbinde mein Handy mit dem geöffnetem Socket Server und sende dann einzelne Strings.
    Diese möchte ich mit AutoIt auswerten.

    Wenn ich den Code von Xenon verwende, dann kann ich mich verbinden.
    Wenn ich dann einen Datenwert sende, bekomme ich den angezeigt.
    Anschließend gleich das die Verbindung vom Client unterbrochen worden ist.
    Er wieder bereit ist neue verbindungen einzugehen und schon mein Handy neu am Socket gecoppelt ist.

    Nun kann ich erneut den Datensatz (ein paar Buchstaben) senden und die verbindung bricht wieder ab...


    Nun könnte man sicherlich sagen, das ist ein Problem meines Handys, aber ich habe eine MiniSocketServer über die Konsole per Java laufen, und da passiert das nicht.
    Da verbinde ich mich, sende so viel wie ich will, und wenn ich die Aplikation beende, wird die verbindung getrennt.

    Kann das an dem Script liegen ?

    LG Tim


    Edit: Ich habe soeben versucht die Daten zurückzusenden wenn ich sie empfangen habe. Dann geht es Problemlos und die Verbindung verreckt nicht mehr.
    Warum muss das so sein ?

  • Du hast wohl etwas falsch gemacht.

    Spoiler anzeigen
    [autoit]

    TCPStartup()
    $hMainSocket = TCPListen(@IPAddress1, 11111)

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

    While 1
    ConsoleWrite("waiting for a client..." & @LF)
    Do
    $hClientSocket = TCPAccept($hMainSocket)
    Until $hClientSocket <> -1
    ConsoleWrite("new client connected at socket " & $hClientSocket & @LF)
    While 1
    $sReceivedData = TCPRecv($hClientSocket, 1024)
    If @error Then
    ExitLoop
    ElseIf $sReceivedData <> "" Then
    TCPSend($hClientSocket, $sReceivedData)
    ConsoleWrite("receiced data: '" & $sReceivedData & "'" & @LF)
    EndIf
    WEnd
    TCPCloseSocket($hClientSocket)
    ConsoleWrite("client disconnected!" & @LF)
    WEnd

    [/autoit]

    LG
    Christoph :)

  • Edit: Ich habe soeben versucht die Daten zurückzusenden wenn ich sie empfangen habe. Dann geht es Problemlos und die Verbindung verreckt nicht mehr.
    Warum muss das so sein ?


    Das wird wohl an deinem Client liegen und nicht an deinem Server. Der Client trennt die Verbindung vermutlich nach kurzer Zeit, wenn er keine Antworten bekommt und auch erstmal nichts mehr senden möchte, was ja auch irgendwo Sinn macht. Es macht aber keinen Sinn hier über soetwas zu reden, wenn man nur einen Teil des Codes hat, woher sollen wir wissen was dein Client tut? Welche Version des Serverscriptes du nun benutzt ist auch nicht wirklich klar, vielleicht einfach mal die aktuelle Fassung posten und sofern möglich auch den Code des Clients auf deinem Android Gerät.

  • Danke für die Antwort.
    Ja, so wird es wohl sein.

    Auf meinem Handy (i-P4) verwende ich die NetIO Application: http://netio.davideickhoff.de/

    Der aktuelle und auch funktionierende Code ist folgender:

    Spoiler anzeigen
    [autoit]


    #include <Inet.au3>
    #include <Winamp_Library.au3>
    #include <Date.au3>

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

    TraySetIcon("apple_iphone.ico")
    Opt("TrayMenuMode", 1)

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

    $meineIP = "192.168.178.49"
    $meinport = "11111"
    Dim $sendedBytes
    Global $Secs, $Mins, $Hour

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

    TCPStartup()
    $hMainSocket = TCPListen($meineIP,$meinport)

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

    While 1
    TrayTip("Gestartet","Bereit um Verbindung einzugehen",1,1)

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

    Do
    $hClientSocket = TCPAccept($hMainSocket) ;Warten bis sich ein Gerät verbindet
    Until $hClientSocket <> -1

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

    TrayTip("Verbunden","Ein Gerät hat sich erfolgreich verbunden",1,1)

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

    While 1
    $sReceivedData = TCPRecv($hClientSocket, 1024) ; Wenn eine Socketverbindung hergestellt wurde, empfange ein Paket vom Client ($connectedSocket)
    If @error Then ;Wenn die Verbindung unterbrochen wird
    ExitLoop
    ElseIf $sReceivedData <> "" Then ;überprüfen was die gesendeten Daten beinhalten

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

    If $sReceivedData = ("WA_titel"&@LF) Then ; Überprüfen ob die empfangenen Daten einen besonderen Rückgabeweret brauchen

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

    ElseIf $sReceivedData = ("WA_time1"&@LF) Then

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

    ElseIf $sReceivedData = ("WA_time2"&@LF) Then

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

    ElseIf $sReceivedData = ("WA_time3"&@LF) Then

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

    ElseIf $sReceivedData = ("WA_getv"&@LF) Then

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

    ElseIf $sReceivedData = ("PC_socket"&@LF) Then

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

    ElseIf $sReceivedData = ("PC_ip"&@LF) Then

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

    ElseIf $sReceivedData = ("PC_name"&@LF) Then

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

    Else
    $sendedBytes = TCPSend($hClientSocket,$sReceivedData) ; Daten als bestätigung zurücksenden
    If $sendedBytes = 0 Then TrayTip("Error","Keine Verbindung zum Clienten",1,3); Wenn der Rückgabewert von TCPSend(...) 0 ist, Fehlermeldung ausgeben
    ConsoleWrite($sReceivedData)
    EndIf

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

    ;~ --------------------------------------------Winamp
    If $sReceivedData = ("WA_start"&@LF) Then ;starten
    _Winamp_Start(-1, 1)

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

    ElseIf $sReceivedData = ("WA_titel"&@LF) Then ;schließen
    TCPSend($hClientSocket,_Winamp_GetCurrentTrackTitle())

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

    ElseIf $sReceivedData = ("WA_getv"&@LF) Then ;schließen
    TCPSend($hClientSocket,StringToBinary(_Winamp_GetVolume(),4))

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

    ElseIf $sReceivedData = ("WA_time1"&@LF) Then ;Spielzeit in Zahlen
    $tracktime = _Winamp_GetCurrentTrackOutputTime(-1)
    _TicksToTime($tracktime,$Hour,$Mins,$Secs)
    $tracktime = StringFormat("%02i:%02i:%02i", $Hour, $Mins, $Secs)
    TCPSend($hClientSocket,$tracktime)

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

    ElseIf $sReceivedData = ("WA_time3"&@LF) Then ;Spielzeit in Zahlen
    $tracktime = _Winamp_GetCurrentTrackOutputTime(0)
    _TicksToTime($tracktime,$Hour,$Mins,$Secs)
    $tracktime = StringFormat("%02i:%02i:%02i", $Hour, $Mins, $Secs)
    TCPSend($hClientSocket,$tracktime)

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

    ElseIF $sReceivedData = ("WA_time2"&@LF) Then
    $tracktime = _Winamp_GetCurrentTrackOutputTime(-1) ; bisherige Spielzeit in millisekunden
    $tracktimeganz = _Winamp_GetCurrentTrackOutputTime(0) ; Spielzeit des Titels
    $proz = $tracktimeganz/255 ; Prozentualen Teil ermitteln
    $percentout = $tracktime/$proz ; Schauen wieviel prozent schon gelaufen sind
    $percentout = Round($percentout,0) ; keine Nachkommerstellen
    TCPSend($hClientSocket,StringToBinary($percentout,4))

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

    ElseIf $sReceivedData = ("WA_close"&@LF) Then ;schließen
    _Winamp_Close()

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

    ElseIf $sReceivedData = ("WA_play"&@LF) Then ;play
    _Winamp_Play()

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

    ElseIf $sReceivedData = ("WA_pause"&@LF) Then ;play/pause
    _Winamp_PlayPauseToggle()

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

    ElseIf $sReceivedData = ("WA_titelzur"&@LF) Then ; zur
    _Winamp_Previous()

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

    ElseIf $sReceivedData = ("WA_titelvor"&@LF) Then ; vor
    _Winamp_Next()

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

    ElseIf $sReceivedData = ("WA_titelzurs"&@LF) Then ; zur
    _Winamp_Seek(-1)

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

    ElseIf $sReceivedData = ("WA_titelvors"&@LF) Then ; vor
    _Winamp_Seek(-2)

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

    ElseIf StringInStr($sReceivedData,"WA_vol_") Then
    $sReceivedData = StringReplace($sReceivedData,"WA_vol_","")
    $sReceivedData = StringReplace($sReceivedData,@LF,"")
    _Winamp_SetVolume($sReceivedData)

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

    ElseIf StringInStr($sReceivedData,"WA_time4_") Then
    $sReceivedData = StringReplace($sReceivedData,"WA_time4_","")
    $sReceivedData = StringReplace($sReceivedData,@LF,"")
    ConsoleWrite($sReceivedData)

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

    $tracktimeganz = _Winamp_GetCurrentTrackOutputTime(0) ; Spielzeit des Titels
    $proz = $tracktimeganz/255 ; Prozentualen Teil ermitteln
    $percentout = $sReceivedData*$proz ; Schauen wieviel prozent schon gelaufen sind
    $percentout = Round($percentout,0)

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

    _Winamp_Seek($percentout)

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

    ConsoleWrite($tracktimeganz&" : "&$percentout)

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

    ;~ --------------------------------------------Winamp

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

    ;~ --------------------------------------------PC
    ElseIf $sReceivedData = ("PC_shutdown"&@LF) Then ; vor
    Shutdown(9)

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

    ElseIf $sReceivedData = ("PC_ip"&@LF) Then
    TCPSend($hClientSocket,StringToBinary(_GetIP(),4))

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

    ElseIf $sReceivedData = ("PC_name"&@LF) Then
    TCPSend($hClientSocket,StringToBinary(@ComputerName,4))

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

    ElseIf $sReceivedData = ("PC_socket"&@LF) Then
    TCPSend($hClientSocket,StringToBinary($hClientSocket,4))
    EndIf
    ;~ --------------------------------------------PC
    EndIf
    WEnd

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

    TCPCloseSocket($hClientSocket)

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

    TrayTip("Error","Der Client hat die Verbindung getrennt",1,3)
    WEnd

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