Simpler TCP Chat - Server reagiert nach 1 Nachricht nicht mehr

  • Hey,
    Ich habe mal einen Simplen TCP Chat für meinen LAN Netzwerk erstellt für 3 Personen(mit mir). Es war so gedacht, dass jede Person beide Programme(Server.au3 und Client.au3) immer ausführt.. die Server.au3 kommt dann in den Autostart und die Client.au3 wird ausgeführt, sobald man eine Nachricht senden will. Also kann jeder jedem sogesagt "direkt" eine Nachricht senden ohne Umwege von mehreren Servern.
    Problem: Sobald die Server.au3 eine Nachricht empfängt wird sie als Msgbox wiedergeben, aber danach reagiert der Server nicht mehr und keine Nachrichten werden mehr empfangen..

    Server.au3

    Spoiler anzeigen
    [autoit]


    $ip = @IPAddress1
    $port = 33899

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

    TCPStartup()
    $listen = TCPListen($ip,$port)
    If $listen = -1 Then Exit
    $Socket = -1
    Do
    $Socket = TCPAccept($listen)
    Until $Socket <> -1

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

    $secondip = SocketToIP($Socket)

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

    While 1
    $recv = TCPRecv($Socket, 2048)
    If $recv <> "" Then MsgBox (0,"Nachricht", $secondip & ">" & $recv)
    WEnd

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

    If $Socket <> -1 Then TCPCloseSocket ($Socket)
    TCPShutdown()

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

    Func SocketToIP($SHOCKET)
    Local $sockaddr, $aRet
    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")
    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
    $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
    If Not @error Then $aRet = $aRet[0]
    Else
    $aRet = 0
    EndIf
    $sockaddr = 0
    Return $aRet
    EndFunc

    [/autoit]


    Client.au3

    Spoiler anzeigen
    [autoit]


    #include <ButtonConstants.au3>
    #include <ComboConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    $port = 33899

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

    $Form1 = GUICreate("Nachricht Senden", 357, 133, 377, 344)
    GUISetBkColor(0xFFFFFF)
    $Input1 = GUICtrlCreateInput("Nachricht", 8, 48, 345, 28)
    GUICtrlSetFont(-1, 11, 400, 0, "Comic Sans MS")
    $Button1 = GUICtrlCreateButton("Senden!", 8, 88, 345, 33)
    GUICtrlSetFont(-1, 12, 400, 0, "Comic Sans MS")
    $Combo1 = GUICtrlCreateCombo("Empfänger", 8, 8, 345, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
    GUICtrlSetData(-1, "Person1|Person2|Person3")
    GUICtrlSetFont(-1, 11, 400, 0, "Comic Sans MS")
    GUISetState(@SW_SHOW)

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button1
    If GUICtrlRead($Combo1) = "Empfänger" Then $ip = @IPAddress1
    If GUICtrlRead($Combo1) = "Person1" Then $ip = "192.168.2.112"
    If GUICtrlRead($Combo1) = "Person2" Then $ip = "192.168.2.103"
    If GUICtrlRead($Combo1) = "Person3" Then $ip = "192.168.2.100"
    Local $Socket, $Data
    TCPStartup()
    Dim $Socket = -1
    $Socket = TCPConnect ($ip,$port)
    $Nachricht = GUICtrlRead ($Input1)
    TCPSend ($Socket,$Nachricht)
    EndSwitch
    WEnd

    [/autoit]
  • Die Frage nach dem Wieso spare ich mir jetzt einfach mal...

    Ein Problem ist, dass der Server solange wartet, bis jemand verbunden ist. Dieser Client kann dann Nachrichten zu dem Server schicken. Es wird allerdings weder überprüft, ob der Client die Verbindung trennt, noch ob ein anderer Client versucht zu verbinden. Deswegen können dann auch von möglichen anderen Clients keine Nachrichten gesendet werden.

    Ein anderes Problem ist, dass du in dem Client in einer Schleife TCPStartup() verwendest, aber nie TCPShutdown() und TCPCloseSocket(),

  • Ein etwas seltsames Konzept aber nun gut. Bei dieser Variante müsstest du die Verbindung nach jeder Nachricht wieder trennen, sprich TCPCloseSocket nach TCPSend beim Client. (TCPStartup kommt ganz am Anfang und nicht mittendrin). Beim Server müsstest du das While 1 gleich unter TCPStartup machen, dann verbindet er sich immer neu. Und auch hier am Ende der schleife wieder TCPCloseSocket. Ich würde dir aber dringen empfehlen das ganze nochmal neu zu schreiben, so dass du nicht immer eine neue Verbindung erstellst.

    EDIT: Zu langsam...

    Gruss Shadowigor