TCP - Server empfängt nicht oder nur einmal :(

  • Hallöchen zusammen.

    Anhanden der Wiki Artikel versuche ich einen Client/Server zu schreiben.

    Leider habe ich das Problem, dass der Server die Daten nicht wirklich empfängt oder teilweise funktioniert es einmalig.

    Habe ich mich "verschrieben"?

    Spoiler anzeigen
    [autoit]

    ;Check startup parameters (exit when no parameters are set!)
    if $CmdLine[0] = 0 Then
    exit
    EndIf

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

    ;Server or Client
    Switch $CmdLine[1]
    case 1 ;Server

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

    ;Start TCP service
    TCPStartup()

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

    ;Create listening socket
    $MainSocket = TCPListen(@IPAddress1,555)

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

    ;Exit if socket could not be created!
    If $MainSocket = -1 then
    exit
    EndIf
    while 1
    ;Initialize a variable to represent a connection
    $ConnectedSocket = -1

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

    ;Wait for and accept a connection
    Do
    $ConnectedSocket = TCPAccept($MainSocket)
    Until $ConnectedSocket <> -1

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

    While 1
    $Recv = TCPRecv($ConnectedSocket,4096)
    if $Recv <> "" then TrayTip("SERVER","Received " & $Recv,1000)
    if @error then
    ExitLoop
    EndIf
    WEnd

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

    ;If existing, close open socket
    If $ConnectedSocket <> -1 then
    TCPCloseSocket($ConnectedSocket)
    TrayTip("SERVER","Closed a ConnectedSocket",1000)
    EndIf

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

    WEnd
    ;Shutdown TCP service
    TCPShutdown()

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

    case 2 ;Client
    ;Start TCP service
    TCPStartup()

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

    ;Initialize a variable to represent a connection
    $ConnectedSocket = -1

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

    ;Attemp to connect to the server
    $ConnectedSocket = TCPConnect(@IPAddress1,555)

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

    ;Exit on error
    If @error then
    exit
    EndIf

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

    TCPSend($ConnectedSocket,"TEST")

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

    ;Shutdown TCP service
    TCPShutdown()
    EndSwitch

    [/autoit]

    Einmal editiert, zuletzt von iwasready (16. März 2010 um 16:12)

    • Offizieller Beitrag

    Hi,

    es gibt doch schon so viele Chatprogramme. Hier ist ein altes von mir :)
    Einfach 2x kompilieren und dann doppelt starten. Listen beim anderen connect und umgekehrt.
    Das Script ist beides Server und Client.

    Spoiler anzeigen
    [autoit]

    ; MegaChat
    #include <File.au3>
    #include <GuiIPAddress.au3>
    #include <Inet.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

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

    Opt("OnExitFunc", "_endscript")
    Opt("MustDeclareVars", 1)

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

    Global $title = "MegaChat", $l_port_startValue = 10000, $r_port_startValue = 20000, $left = 100, $logPath = 'MegaChat.log'

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

    If WinExists($title) Then
    $title &= ' 2'
    $l_port_startValue = 20000
    $r_port_startValue = 10000
    $left += 500
    $logPath = 'MegaChat2.log'
    EndIf

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

    Global $GUI
    Global $l_hostname_I, $l_ip_IC, $l_port_I, $listen_B
    Global $r_hostname_I, $r_ip_IC, $r_port_I, $connect_B
    Global $comm_E, $send_E, $send_B

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

    #Region ### START Koda GUI section ### Form=c:\dokumente und einstellungen\xf01145\eigene dateien\chat.kxf
    $GUI = GUICreate($title, 445, 508, $left, 111)

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

    GUICtrlCreateGroup("Local settings", 10, 10, 420, 105)
    GUICtrlCreateLabel("Hostname", 20, 30, 52, 17)
    $l_hostname_I = GUICtrlCreateInput(@ComputerName, 105, 25, 131, 21)
    GUICtrlCreateLabel("IP-address", 20, 55, 54, 17)
    $l_ip_IC = _GUICtrlIpAddress_Create($GUI, 105, 50, 130, 21)
    _GUICtrlIpAddress_Set($l_ip_IC, @IPAddress1)
    GUICtrlCreateLabel("Listener-Port", 20, 80, 63, 17)
    $l_port_I = GUICtrlCreateInput($l_port_startValue, 105, 75, 131, 21)
    $listen_B = GUICtrlCreateButton("Listen", 275, 25, 120, 25, $WS_GROUP)
    GUICtrlCreateGroup("", -99, -99, 1, 1)

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

    GUICtrlCreateGroup("Remote settings", 10, 115, 420, 105)
    GUICtrlCreateLabel("Hostname", 20, 135, 52, 17)
    $r_hostname_I = GUICtrlCreateInput("not connected ...", 105, 130, 131, 21)
    GUICtrlCreateLabel("IP-address", 20, 160, 54, 17)
    $r_ip_IC = _GUICtrlIpAddress_Create($GUI, 105, 155, 130, 21)
    _GUICtrlIpAddress_Set($r_ip_IC, @IPAddress1)
    GUICtrlCreateLabel("Listener-Port", 20, 185, 63, 17)
    $r_port_I = GUICtrlCreateInput($r_port_startValue, 105, 180, 131, 21)
    $connect_B = GUICtrlCreateButton("Connect", 280, 130, 120, 25, $WS_GROUP)
    GUICtrlCreateGroup("", -99, -99, 1, 1)

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

    GUICtrlCreateGroup("Communication summary", 10, 220, 420, 155)
    $comm_E = GUICtrlCreateEdit("", 15, 235, 410, 134)
    GUICtrlCreateGroup("", -99, -99, 1, 1)

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

    GUICtrlCreateGroup("Communication send", 10, 375, 420, 95)
    $send_E = GUICtrlCreateEdit("", 15, 390, 410, 74)
    GUICtrlCreateGroup("", -99, -99, 1, 1)

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

    $send_B = GUICtrlCreateButton("Send", 10, 475, 90, 25, $WS_GROUP)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

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

    ; Start The TCP Services
    ;==============================================
    TCPStartup()
    ; Initialize a variable to represent a server-connection
    ;==============================================
    Global $ConnectedSocket = -1
    ; Initialize a variable to represent a client-connection
    ;==============================================
    Global $ConnectedToSocket = -1
    Global $recv

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

    _main()

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

    Func _main()
    Local $nMsg

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

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $listen_B
    _listen()
    Case $connect_B
    _connect()
    Case $send_B
    If $ConnectedToSocket <> -1 Then
    _send()
    Else
    _FileWriteLog($logPath, 'You are not connected!')
    MsgBox(16, 'Error', 'You are not connected!', 5)
    EndIf
    EndSwitch
    If $ConnectedSocket <> -1 Then _receive()
    WEnd
    EndFunc ;==>_main

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

    Func _send()
    Local $txt = GUICtrlRead($send_E)
    If $txt <> '' Then TCPSend($ConnectedToSocket, $txt)
    ; If the send failed with @error then the socket has disconnected
    ;----------------------------------------------------------------
    If @error Then
    _FileWriteLog($logPath, 'TCPSend error')
    Else
    GUICtrlSetData($comm_E, _
    @UserName & " : " & $txt & @CRLF & GUICtrlRead($comm_E))
    GUICtrlSetData($send_E, '')
    EndIf
    EndFunc ;==>_send

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

    Func _connect()
    ;Attempt to connect to SERVER at its IP and PORT
    ;=======================================================
    $ConnectedToSocket = TCPConnect(_GUICtrlIpAddress_Get($r_ip_IC), GUICtrlRead($r_port_I))

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

    ; If there is an error... show it
    If @error Then
    MsgBox(4112, "Error", "TCPConnect failed with WSA error: " & @error & @CRLF & 'Maybe nobody is listening ...')
    _FileWriteLog($logPath, 'Connecting error')
    EndIf
    EndFunc ;==>_connect

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

    Func _receive()
    ; Try to receive (up to) 2048 bytes
    ;----------------------------------------------------------------
    $recv = TCPRecv($ConnectedSocket, 2048)

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

    ; If the receive failed with @error then the socket has disconnected
    ;----------------------------------------------------------------
    If @error Then
    _FileWriteLog($logPath, 'Disconnected')
    $ConnectedSocket = -1
    EndIf

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

    ; Update the edit control with what we have received
    ;----------------------------------------------------------------
    If $recv <> "" Then GUICtrlSetData($comm_E, _
    GUICtrlRead($r_hostname_I) & " -> " & $recv & @CRLF & GUICtrlRead($comm_E))
    EndFunc ;==>_receive

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

    Func _listen()
    ; Create a Listening "SOCKET"
    ;==============================================
    Local $MainSocket = TCPListen(@IPAddress1, GUICtrlRead($l_port_I), 100)
    If $MainSocket = -1 Then
    _FileWriteLog($logPath, 'TCPListen error')
    Exit
    EndIf

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

    ;Wait for and Accept a connection
    ;==============================================
    Local $start = TimerInit()
    Do
    $ConnectedSocket = TCPAccept($MainSocket)
    Until $ConnectedSocket <> -1 Or (TimerDiff($start) > 25000)

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

    ; Get IP of client connecting
    Local $szIP_Accepted = SocketToIP($ConnectedSocket)
    GUICtrlSetData($r_hostname_I, _TCPIpToName($szIP_Accepted))
    EndFunc ;==>_listen

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

    ; Function to return IP Address from a connected socket.
    ;----------------------------------------------------------------------
    Func SocketToIP($SHOCKET)
    Local $sockaddr, $aRet

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

    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")

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

    $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

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

    $sockaddr = 0

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

    Return $aRet
    EndFunc ;==>SocketToIP

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

    Func _endscript()
    TCPCloseSocket($ConnectedSocket)
    TCPShutdown()
    Exit (0)
    EndFunc ;==>_endscript

    [/autoit]

    Mega

  • geht er nicht aus dieser Schleife raus, da er nichts empfängt wird doch @error von TCPRecv() gesetzt:


    [autoit]


    While 1
    $Recv = TCPRecv($ConnectedSocket,4096)
    if $Recv <> "" then TrayTip("SERVER","Received " & $Recv,1000)
    if @error then
    ExitLoop
    EndIf
    WEnd

    [/autoit]

    Edit: Frage: wie bekommt man das Eingerückt dargestellt???

  • HalliHalloSchat,

    wenn du das mit @error lösen willst, musst du die Abfrage DIREKT nach dem TCPRecv einbauen, sonst wird der Inhalt des Makro von der Funktion TrayTip überschrieben..
    oder du speicherst es und fragst es erst später ab, so zb:

    [autoit]


    Do
    $recv = TCPRecv($socket,8192)
    $err = @error
    If $recv <> "" Then TrayTip("TCPRecv",$recv)
    Until $err = -1

    [/autoit]
    • Offizieller Beitrag

    STRG+T in SciTE

    Ja ja, die gute alte Reihenfolge :D