Daten an anderen PC im Netzwerk senden

  • Ich möchte Daten von PC A, nach PC B senden ... ich denke das geht am besten per TCP, denn dass soll nur im Intranet geschehen.

    Ich habe mal aus den Beispielen von TCPRecv() den Server und TCPSend() den Client ein Programm geschrieben, dass senden und verschicken kann:

    Fkt. zum senden und empfangen von TCP
    [autoit]

    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

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

    #include <GuiButton.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <Misc.au3>

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

    Opt('MustDeclareVars', 1)
    Opt("TrayAutoPause", 0) ; Keine Pause, bei Klick
    Opt("TrayIconDebug", 1) ; zeige Debug

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

    Example()

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

    func Example()
    ; Richte einige wiederverwendbare Informationen ein.
    ; Richte deine öffentliche IP Adresse (@IPAddress1) hier ein.
    ;local $IPADDRESS = TCPNameToIP("chrisx312")

    local $szIPADDRESS = @IPAddress2
    local $nPORT = 8763
    local $MainSocket, $GOOEY, $edit, $ConnectedSocket, $szIP_Accepted, $input, $knopf
    local $msg, $recv, $SendenSocket, $IPADDRESS = "192.168.1.60", $IP_Accepted, $iTimerC, $iTimerS, $iTimerDiff = 5*1000

    $IPADDRESS = InputBox("andere IP Adresse", "andere IP Adresse:", $IPADDRESS)
    if @error or $IPADDRESS = "" then return false

    ; Startet den TCP Service
    ;==============================================
    TCPStartup()

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

    ; Erstellt einen lauschenden Port.
    ; Benutzt deine IP Adresse und den Port 33891. (Oben angegeben)
    ;==============================================
    $MainSocket = TCPListen($szIPADDRESS, $nPORT)

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

    ; Wenn die Socketerstellung fehl schlägt, dann wird das Programm beendet.
    if $MainSocket = -1 then
    MsgBox(4112, "Fehler", "Wenn die Socketerstellung fehl schlägt, dann wird das Programm beendet: " & @error)
    exit
    endif

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

    ; Erstellt eine GUI für Messages.
    ;==============================================
    $GOOEY = GUICreate(@ComputerName & " (IP: " & $szIPADDRESS & ")", 300, 230)
    $edit = GUICtrlCreateEdit("", 10, 10, 280, 180, $ES_READONLY)
    $input = GUICtrlCreateInput("", 10, 200, 210, 20)
    $knopf = GUICtrlCreateButton("senden", 230, 200, 60, 20)
    GUISetState()

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

    ; Initialisiert eine Variable um eine Verbindung anzugeben
    ;==============================================
    $SendenSocket = TCPConnect($IPADDRESS, $nPORT)
    if $SendenSocket <> -1 then
    GUICtrlSetData($edit, $szIPADDRESS & " (sagt) " & "senden gestartet" & @CRLF & GUICtrlRead($edit))
    else
    GUICtrlSetData($edit, $szIPADDRESS & " (sagt) " & "senden nicht gestartet" & @CRLF & GUICtrlRead($edit))
    endif

    $ConnectedSocket = TCPAccept($MainSocket)
    if $ConnectedSocket <> -1 then
    GUICtrlSetData($edit, $szIPADDRESS & " (sagt) " & "empfangen gestartet" & @CRLF & GUICtrlRead($edit))
    else
    GUICtrlSetData($edit, $szIPADDRESS & " (sagt) " & "empfangen nicht gestartet" & @CRLF & GUICtrlRead($edit))
    endif

    $iTimerC = $iTimerS = TimerInit()

    While 1
    $msg = GUIGetMsg()
    ;MsgBox(0, "", TimerDiff($iTimer) & "-" & $iTimer+$iTimerDiff & " = " & TimerDiff($iTimer) - ($iTimer+$iTimerDiff))
    if $SendenSocket = -1 and TimerDiff($iTimerS) > $iTimerDiff then
    $SendenSocket = TCPConnect($IPADDRESS, $nPORT)
    $iTimerS = TimerInit()
    if $SendenSocket <> -1 then
    ; Bekommt die IP des verbundenen Clients
    ;$IP_Accepted = SocketToIP($SendenSocket)

    GUICtrlSetData($edit, $szIPADDRESS & " (sagt) " & "senden gestartet" & @CRLF & GUICtrlRead($edit))
    else
    GUICtrlSetData($edit, $szIPADDRESS & " (sagt) " & "senden nicht gestartet" & @CRLF & GUICtrlRead($edit))
    endif
    endif

    ; Wartet auf und akzeptiert eine Verbindung
    ;==============================================
    if $ConnectedSocket = -1 and TimerDiff($iTimerC) > $iTimerDiff then

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

    $ConnectedSocket = TCPAccept($MainSocket)
    $iTimerC = TimerInit()
    if $ConnectedSocket <> -1 then
    ; Bekommt die IP des verbundenen Clients
    ;$szIP_Accepted = SocketToIP($ConnectedSocket)

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

    ; GUI Message Schleife
    ;==============================================
    GUICtrlSetData($edit, $szIPADDRESS & " (sagt) " & "empfangen gestartet" & @CRLF & GUICtrlRead($edit))
    else
    GUICtrlSetData($edit, $szIPADDRESS & " (sagt) " & "empfangen nicht gestartet" & @CRLF & GUICtrlRead($edit))
    endif
    elseif $ConnectedSocket <> -1 then

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

    ; Versucht Daten zu empfangen, bis zu 2048 bytes
    ;----------------------------------------------------------------
    $recv = TCPRecv($ConnectedSocket, 2048)

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

    ; Wenn der Empfang mit @error fehlschlägt, dann hat sich der Socket getrennt.
    ;----------------------------------------------------------------
    if @error then
    GUICtrlSetData($edit, $szIPADDRESS & " (sagt) " & "empfangen beendet" & @CRLF & GUICtrlRead($edit))
    $ConnectedSocket = -1
    ;exitloop
    endif

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

    ; Aktualisiert das Input-Control mit dem, was wir empfangen haben.
    ;----------------------------------------------------------------
    if $recv <> "" then GUICtrlSetData($edit, $IPADDRESS & " (sendet) " & $recv & @CRLF & GUICtrlRead($edit))
    endif

    ; GUI beendet
    ;--------------------
    if $msg = $GUI_EVENT_CLOSE then exitloop

    ; Nachricht senden
    if $msg = $knopf or (_IsPressed("0D") and WinActive($GOOEY)) then
    ; Wir sollten Daten in $szData haben... Lasst uns versuchen, sie durch unseren verbundenen Socket zu versenden.
    TCPSend($SendenSocket, GUICtrlRead($input))

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

    ; Wenn das Senden mit @error fehlgeschlagen ist, dann ist der Socket getrennt.
    ;----------------------------------------------------------------
    if @error then
    GUICtrlSetData($edit, $szIPADDRESS & " (sagt) " & "senden beendet/nicht gestartet" & @CRLF & GUICtrlRead($edit))
    $SendenSocket = -1
    ;exitloop
    else
    if GUICtrlRead($input) <> "" then
    GUICtrlSetData($edit, $szIPADDRESS & " (sendet) " & GUICtrlRead($input) & @CRLF & GUICtrlRead($edit))
    GUICtrlSetData($input, "")
    endif
    endif
    endif
    wend

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

    if $ConnectedSocket <> -1 then TCPCloseSocket($ConnectedSocket)
    if $SendenSocket <> -1 then TCPCloseSocket($SendenSocket)

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

    TCPShutdown()
    endfunc ;==>Example

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

    ; Funktion um die IP Adresse eines verbundenen Sockets wiederzugeben.
    ;----------------------------------------------------------------------
    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]


    Es funktioniert auch soweit gut!
    Man kann Nachrichten versehen, mehr nicht.
    Kann man das noch vereinfachen?

    Das obige ist nur ein Test, ich möchte das Programm umschreiben, sodass PC A einen String (ca. 5kb) an PC B sendet. PC B kontrolliert diesen String und gibt eine kurze Antwort (8bytes) an PC A.
    PC A läuft immer, PC B ist nicht immer an. PC A soll prüfen ob PC B an ist, wenn ja sendet es den String, falls nein eben nicht.
    Das obige Skript möchte ich in der Form im schreiben. Macht das Sinn?
    Gibt es noch eine bessere Möglichkeit?

  • ja, brauche ich das?
    Ich möchte ja keine Dateien versenden ...

    Ich habe das jetzt so gelöst, indem ich Server und Client wieder getrennt habe, weiß nicht wieso ich das so kompliziert machen wollte:

    Client
    [autoit]

    #include "funktionen.au3"

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

    Opt("TrayAutoPause", 0) ; Keine Pause, bei Klick
    Opt("TrayIconDebug", 1) ; zeige Debug

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

    $sTitel = "Client"

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

    ;MsgBox(0, $sTitel, "Client startet Empfangen.")
    $iSocket = empfangen_start($iIpServer, $iPort)
    if $iSocket = false then
    MsgBox(16, $sTitel, "Empfangen nicht erfolgreich gestartet." & @CRLF & "Vielleicht ist schon eine Client-Instanz offen?")
    exit
    endif

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

    ;MsgBox(0, $sTitel, "Warte auf Nachricht von Server.")
    $iSocket = empfangen_test($iSocket)
    $sEmpfangen = empfangen($iSocket)
    if $sEmpfangen <> false then
    ;MsgBox(0, $sTitel, "Nachricht wurde erfolgreich empfangen.")

    $bBeenden = beenden($iSocket)
    if $bBeenden = false then
    MsgBox(16, $sTitel, "Fehler beim TCP-Empfangen beenden.")
    exit
    endif

    ;MsgBox(0, $sTitel, "Testen ob Server noch an.")
    $cSocket = senden_start($iIpClient, $iPort)
    if $cSocket <> false then
    ;MsgBox(0, $sTitel, "Client ist an.")
    $sNachricht = '"' & $sEmpfangen & '" plus ' & @CRLF & "der Senf vom Clienten."

    $iBytes = senden($cSocket, $sNachricht)
    if $iBytes <> false then
    ;MsgBox(0, $sTitel, "Nachricht wurde gesendet.")
    else
    MsgBox(16, $sTitel, "Nachricht kontne nicht gesendet werden.")
    exit
    endif

    $bBeenden = beenden($cSocket)
    if $bBeenden = false then
    MsgBox(16, $sTitel, "Fehler beim TCP-Empfangen beenden.")
    exit
    endif
    else
    MsgBox(16, $sTitel, "Server ist nicht mehr an.")
    exit
    endif
    else
    MsgBox(16, $sTitel, "Es wurde keine Nachricht empfangen.")
    exit
    endif

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

    MsgBox(0, $sTitel, $sEmpfangen)

    [/autoit]
    Server
    [autoit]

    #include "funktionen.au3"

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

    Opt("TrayAutoPause", 0) ; Keine Pause, bei Klick
    Opt("TrayIconDebug", 1) ; zeige Debug

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

    $sTitel = "Server"

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

    ;MsgBox(0, $sTitel, "Testen ob Client an.")
    $cSocket = senden_start($iIpClient, $iPort)
    if $cSocket <> false then
    ;MsgBox(0, $sTitel, "Client ist an.")
    $sNachricht = "Das ist die Testnachricht vom Server."

    $iBytes = senden($cSocket, $sNachricht)
    if $iBytes <> false then
    ;MsgBox(0, $sTitel, "Nachricht wurde gesendet.")
    else
    MsgBox(16, $sTitel, "Nachricht kontne nicht gesendet werden.")
    exit
    endif

    $bBeenden = beenden($cSocket)
    if $bBeenden = false then
    MsgBox(16, $sTitel, "Fehler beim TCP-Senden beenden.")
    exit
    endif

    $iSocket = empfangen_start($iIpClient, $iPort)
    if $iSocket = false then
    MsgBox(16, $sTitel, "Empfangen nicht erfolgreich gestartet")
    exit
    endif

    $iSocket = empfangen_test($iSocket)
    $sEmpfangen = empfangen($iSocket)
    if $sEmpfangen <> false then
    ;MsgBox(0, $sTitel, "Nachricht wurde erfolgreich empfangen.")
    else
    MsgBox(16, $sTitel, "Es wurde keine Nachricht empfangen.")
    exit
    endif

    $bBeenden = beenden($iSocket)
    if $bBeenden = false then
    MsgBox(16, $sTitel, "Fehler beim TCP-Empfangen beenden.")
    exit
    endif
    else
    MsgBox(16, $sTitel, "Client ist nicht an.")
    exit
    endif

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

    MsgBox(0, $sTitel, $sEmpfangen)

    [/autoit]
    Funktionen
    [autoit]


    $iIpClient = "192.168.1.60"
    $iIpServer = "192.168.1.60"
    $iPort = "33456"

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

    ; Starten vom TCP empfangen
    func empfangen_start($iIp = "127.0.0.1", $iPort = "33456")
    TCPStartup()
    if @error then return false

    $iSocket = TCPListen($iIp, $iPort)
    if @error then return false

    return $iSocket
    endfunc

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

    ; Testen ob das gegebnüber bereit
    func empfangen_test($iSocket, $iInterval = 1)
    local $iTimer

    Do
    ;if TimerDiff($iTimer) > $iInterval*1000 then
    $cSocket = TCPAccept($iSocket)
    ;$iTimer = TimerInit()
    ;endif
    Until $cSocket <> -1
    if @error then return false

    return $cSocket
    endfunc

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

    ; Warten bis das gegenüber eine Nachricht ausgibt
    func empfangen($cSocket, $iMax = 2048, $bBin = 0)
    Do
    $sInhalt = TCPRecv($cSocket, $iMax, $bBin)
    Until $sInhalt <> ""
    if @error then return false

    return $sInhalt
    endfunc

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

    ; Beenden der TCP Sende- oder Empfangs- Verbindung
    func beenden($cSocket)
    $bSocket = TCPCloseSocket($cSocket)
    if @error then return false

    $bSocket = TCPShutdown()
    if @error then return false

    return true
    endfunc

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

    ; Starten vom TCP senden
    func senden_start($iIp = "127.0.0.1", $iPort = "33456")
    TCPStartup()
    if @error then return false

    $cSocket = TCPConnect($iIp, $iPort)
    if @error then return false

    return $cSocket
    endfunc

    ; Eine Nachricht per TCP senden
    func senden($cSocket, $sSenden)
    $iBytes = TCPSend($cSocket, $sSenden)
    if @error then return false

    return $iBytes
    endfunc

    [/autoit]


    Ich habe irgendwo einmal gelesen, dass TCPAccept() nach einer gewissen Zeit aufhört, nichts mehr macht, dass man es nur eine bestimmt Anzahl aufrufen kann. Konnte sowas bei mir noch nicht feststellen ...