TCP Send / Recv

  • Hallo zusammen,


    ich möchte im Netzwerk eine Kommunikation zwischen 2 Rechnern ermöglichen.
    Beide PC's sollen dabei sowohl Nachrichten empfangen alsauch senden können.

    Ich hab mir dazu mal die TCP-Funktionen angesehen und diese etwas umgebaut.

    Spoiler anzeigen
    [autoit]


    #include <GUIConstantsEx.au3>

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

    Opt('MustDeclareVars', 1)

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

    ;==============================================
    ;==============================================
    ;SERVER!! Start Me First !!!!!!!!!!!!!!!
    ;==============================================
    ;==============================================

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

    Global $IP=@IPAddress1
    Global $Port=33891

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

    HotKeySet("{F2}", "_Send")
    HotKeySet("{F3}", "_Exit")

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

    Example()

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

    func _exit()
    ConsoleWrite("exit" &@crlf)
    exit
    endfunc

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

    func _send()
    ; Set Some reusable info
    ;--------------------------
    Local $ConnectedSocket, $szData
    ; Set $szIPADDRESS to wherever the SERVER is. We will change a PC name into an IP Address
    ; Local $szServerPC = @ComputerName
    ; Local $szIPADDRESS = TCPNameToIP($szServerPC)
    Local $nPORT = 33892

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

    ; Start The TCP Services
    ;==============================================
    TCPStartup()

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

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

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

    ;Attempt to connect to SERVER at its IP and PORT 33891
    ;=======================================================
    $ConnectedSocket = TCPConnect($IP, $nPORT)

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

    ; If there is an error... show it
    If @error Then
    MsgBox(4112, "Error", "TCPConnect failed with WSA error: " & @error)
    ; If there is no error loop an inputbox for data
    ; to send to the SERVER.
    Else

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

    $szData = InputBox("Ich bin Server 1", @LF & @LF & "Enter data to transmit to the SERVER 2:")
    If @error Or $szData = "" Then Return

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

    TCPSend($ConnectedSocket, $szData)
    EndIf

    endfunc

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

    Func Example()
    ; Set Some reusable info
    ; Set your Public IP address (@IPAddress1) here.
    ; Local $szServerPC = @ComputerName
    ; Local $szIPADDRESS = TCPNameToIP($szServerPC)
    Local $szIPADDRESS = @IPAddress1
    Local $nPORT = 33891
    Local $MainSocket, $GOOEY, $edit, $ConnectedSocket, $szIP_Accepted
    Local $msg, $recv

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

    ; Start The TCP Services
    ;==============================================
    TCPStartup()

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

    ; Create a Listening "SOCKET".
    ; Using your IP Address and Port 33891.
    ;==============================================
    $MainSocket = TCPListen($szIPADDRESS, $nPORT)

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

    ; If the Socket creation fails, exit.
    If $MainSocket = -1 Then Exit

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

    ; Create a GUI for messages
    ;==============================================
    $GOOEY = GUICreate("My Server 1 (IP: " & $szIPADDRESS & ")", 300, 200)
    $edit = GUICtrlCreateEdit("", 10, 10, 280, 180)
    GUISetState()

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

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

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

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

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

    ; Get IP of client connecting
    $szIP_Accepted = SocketToIP($ConnectedSocket)

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

    ; GUI Message Loop
    ;==============================================
    While 1
    $msg = GUIGetMsg()

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

    ; GUI Closed
    ;--------------------
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop

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

    ; 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 ExitLoop

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

    ; Update the edit control with what we have received
    ;----------------------------------------------------------------
    If $recv <> "" Then
    GUICtrlSetData($edit, $szIP_Accepted & " > " & $recv & @CRLF & GUICtrlRead($edit))
    _Send()
    endif

    WEnd

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

    If $ConnectedSocket <> -1 Then TCPCloseSocket($ConnectedSocket)

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

    TCPShutdown()
    EndFunc ;==>Example

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

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

    $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]
    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>

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

    Opt('MustDeclareVars', 1)

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

    Global $IP=@IPAddress1
    Global $Port=33891

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

    HotKeySet("{F2}", "_Send")
    HotKeySet("{F3}", "_Exit")

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

    _send()
    Example()

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

    func _exit()
    exit
    endfunc

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

    func _send()
    ; Set Some reusable info
    ;--------------------------
    Local $ConnectedSocket, $szData
    ; Set $szIPADDRESS to wherever the SERVER is. We will change a PC name into an IP Address
    ; Local $szServerPC = @ComputerName
    ; Local $szIPADDRESS = TCPNameToIP($szServerPC)

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

    ; Start The TCP Services
    ;==============================================
    TCPStartup()

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

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

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

    ;Attempt to connect to SERVER at its IP and PORT 33891
    ;=======================================================
    $ConnectedSocket = TCPConnect($IP, $PORT)

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

    ; If there is an error... show it
    If @error Then
    MsgBox(4112, "Error", "TCPConnect failed with WSA error: " & @error)
    ; If there is no error loop an inputbox for data
    ; to send to the SERVER.
    Else

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

    $szData = InputBox("Ich bin Server2", @LF & @LF & "Enter data to transmit to the SERVER 1:")
    If @error Or $szData = "" Then Return

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

    TCPSend($ConnectedSocket, $szData)
    EndIf

    endfunc

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

    Example()

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

    Func Example()
    ; Set Some reusable info
    ; Set your Public IP address (@IPAddress1) here.
    ; Local $szServerPC = @ComputerName
    ; Local $szIPADDRESS = TCPNameToIP($szServerPC)
    Local $szIPADDRESS = @IPAddress1
    Local $nPORT = 33892
    Local $MainSocket, $GOOEY, $edit, $ConnectedSocket, $szIP_Accepted
    Local $msg, $recv

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

    ; Start The TCP Services
    ;==============================================
    TCPStartup()

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

    ; Create a Listening "SOCKET".
    ; Using your IP Address and Port 33891.
    ;==============================================
    $MainSocket = TCPListen($szIPADDRESS, $nPORT)

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

    ; If the Socket creation fails, exit.
    If $MainSocket = -1 Then Exit

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

    ; Create a GUI for messages
    ;==============================================
    $GOOEY = GUICreate("My Server 2(IP: " & $szIPADDRESS & ")", 300, 200)
    $edit = GUICtrlCreateEdit("", 10, 10, 280, 180)
    GUISetState()

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

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

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

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

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

    ; Get IP of client connecting
    $szIP_Accepted = SocketToIP($ConnectedSocket)

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

    ; GUI Message Loop
    ;==============================================
    While 1
    $msg = GUIGetMsg()

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

    ; GUI Closed
    ;--------------------
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop

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

    ; 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 ExitLoop

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

    ; Update the edit control with what we have received
    ;----------------------------------------------------------------
    If $recv <> "" Then
    GUICtrlSetData($edit, $szIP_Accepted & " > " & $recv & @CRLF & GUICtrlRead($edit))
    _Send()
    endif
    WEnd

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

    If $ConnectedSocket <> -1 Then TCPCloseSocket($ConnectedSocket)

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

    TCPShutdown()
    EndFunc ;==>Example

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

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

    $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]

    Es scheint zu funktionieren, allerdings nur genau einmal :(
    Worin liegt mein Denkfehler?

    Gruß nuts

    P.S. Danke schonmal für die Antworten

  • Mit TCPAccept tust du den user einlassen.
    Das wird nur ein mal im Do Until ausgeführt.
    Also must du das so umbauen wenn TCP Rev @error hat das er dan wieder TCP accept macht.
    Fehler verstanden?

  • das liegt daran, das du in deinem script beim senden/empfangen immer wieder TCPStartup machst und immer wieder erneut versuchst auf den server/client zu connecten, ohne das auf diesen TCPListen läuft, sodass der nicht connecten kann und nix mehr senden kann. bzw. auf deinem server verbindest er sich mit seiner eigenen ip (siehe zeile 13 und 45 im server).
    ich würde dir empfehlen einmal komplett neu anzufangen und dann aber nur 1mal beim start verbinden und über den socket von TCPAccept/TCPConnect kannst du die daten an das andere script senden/empfangen ^^

    Mfg. PCKing


    Mein PC

    CPU: AMD FX 8350 8x4.00GHz
    Ram: 8GB DDR3
    Grafikkarte: Nvidia Geforce GTX 960 (4GB)
    Festplatten: 500GB SSD 1TB HDD
    Laufwerk: Blueray RW+ Brenner

  • normalerweise gibbet dazu oben rechts im forum die such-funktion
    aber ich bin mal nett heute, hier ist das einfachste vom einfachen^^

    Client
    [autoit]

    #include <GUIConstants.au3>
    $ip = InputBox("IP","Server-IP eingeben")

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

    TCPStartup()

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

    GUICreate("client",500,500)
    $edit = GUICtrlCreateEdit("",0,0,500,450)
    $button = GUICtrlCreateButton("Send",0,450,100,50)
    $socket = -1
    Do
    $socket = TCPConnect($ip,50)
    Until $socket <> -1

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

    GUISetState(@SW_SHOW)

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

    While 1
    $send = GUICtrlRead($edit)
    $msg = GUIGetMsg()
    Select
    case $msg = $button
    TCPSend($socket, $send)
    EndSelect
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    WEnd

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

    Func OnAutoItExit()
    TCPShutdown()
    EndFunc

    [/autoit]
    Server
    [autoit]

    #include <GUIConstants.au3>
    $ip = InputBox("IP","Deine IP eingeben")

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

    TCPStartup()
    $main = TCPListen($ip,50,8080)
    GUICreate("Server",350,350)
    $edit = GUICtrlCreateEdit("",0,0,350,350)
    $socket = -1
    Do
    $socket = TCPAccept($main)
    Until $socket <> -1

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

    GUISetState(@SW_SHOW)

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

    While 1
    $msg = GUIGetMsg()
    $recive = TCPRecv($socket,1000)
    If $recive <> "" Then
    GUICtrlSetData($edit, $recive)
    EndIf
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    WEnd

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

    Func OnAutoItExit()
    TCPShutdown()
    EndFunc

    [/autoit]

    Mfg. PCKing


    Mein PC

    CPU: AMD FX 8350 8x4.00GHz
    Ram: 8GB DDR3
    Grafikkarte: Nvidia Geforce GTX 960 (4GB)
    Festplatten: 500GB SSD 1TB HDD
    Laufwerk: Blueray RW+ Brenner