TcpPort, Array & Dateianzeige

  • Moin Leute,

    Ich habe 3 Fragen:

    1. Könnt ihr mir ein Port empfelen den ich für TCP benutzen kann? Also ein Prot der auf den meisten routern freigegeben ist?

    2. Kann man per TCP auch Arrays übertragen oder muss ich sie voher in einem String zusammenfassen?

    3. Ich möchte ein Programm schreiben was mir die Dateinen eines entfernten PCs anzeigt. Muss ich die Anzeige der Dateien Selber schreiben mit ListView oder sowas oder gibt es da schonw as fertiges womit irgendwie was? Also ich wollte dasnn auf dem PC von dem ich die Dateien sehen möche die Dateien mit _FileListToArray (weiß nicht genau ob es richtig geschrieben hab, habe an diesem Pc kein autoit :-() einlesen und dann per TCP übertragen und anschließen auf dem 2 PC anzeigen.

    THX im vorraus

    mfg. Jam00

    • Offizieller Beitrag

    Sirocool, was hat du für eine Firewalleinstellung? Gerade die Ports sollten geschlossen sein.
    Gib mir mal deine IP, dann kann ich dich besser Hacken :P (Is nur ein Scherz)

  • So wie ich das sehe kannst Du mit TCPSend nur einen String senden...

    Willst Du alle Dateien anzeigen lassen oder nur bestimmte Dateien eines Ordners?

    • Offizieller Beitrag

    1. Könnt ihr mir ein Port empfelen den ich für TCP benutzen kann? Also ein Prot der auf den meisten routern freigegeben ist?

    Du kannst niemals davon ausgehen, dass irgendein Port zwingend frei ist (80 mal außen vor). Definiere einen Port für deine Anwendung und teile der Gegenstelle mit, dass dieser Port eine Weiterleitung im Router braucht.
    - Lege einen Bereich von Ports fest, der genutzt werden kann (meide well-kown-ports von Anwendungen, einige findest du in ..system32\drivers\etc\services)
    - starte deine Anwendung mit einem Handshake, das heißt: der Client klappert die Portliste ab, bis er vom Server ein Receive mit z.B. Programmnamen und Protokollversion erhält (kannst du gleich für das Log nutzen).
    So bist du flexibel bei den Ports, falls der Server (warum auch immer) mal auf einen anderen Port ausweichen muß.


    2. Kann man per TCP auch Arrays übertragen oder muss ich sie voher in einem String zusammenfassen?

    Du mußt Byte für Byte übertragen, in einer vorher definierten Blockgröße.

    3. Ich möchte ein Programm schreiben was mir die Dateinen eines entfernten PCs anzeigt. Muss ich die Anzeige der Dateien Selber schreiben mit ListView oder sowas oder gibt es da schonw as fertiges womit irgendwie was? Also ich wollte dasnn auf dem PC von dem ich die Dateien sehen möche die Dateien mit _FileListToArray (weiß nicht genau ob es richtig geschrieben hab, habe an diesem Pc kein autoit :-() einlesen und dann per TCP übertragen und anschließen auf dem 2 PC anzeigen.

    Dafür würde ich eher fertige Software nutzen (TeamViewer). Wenn du ein Inhaltsverzeichnis übermittelst kannst du das natürlich in einem Listview darstellen.

  • @noctis
    Das Beispiel was BugFix gesagt hat ist gut, ungefähr so wie TeamViewer soll es sein

    Zitat von BugFix

    starte deine Anwendung mit einem Handshake, das heißt: der Client klappert die Portliste ab, bis er vom Server ein Receive mit z.B. Programmnamen und Protokollversion erhält (kannst du gleich für das Log nutzen).
    So bist du flexibel bei den Ports, falls der Server (warum auch immer) mal auf einen anderen Port ausweichen muß.

    Das hab ich leider nicht so ganz verstanden, soll ich sowas wie einen Protscanner schreiben oder wie?

    2. Is Klar, muss ich zusammenfasen

    3. Muss leider in AutoIt sein

    mfg. Jam00

  • Einführung in TCP

    Ich red net gern übern heißen brei also fangen wa gleich an x)

    TCP steht für Transmission Control Protocol
    Bei einer TCP verbindung wird im gegensatz zu einer UDP Verbindung ein virtueller kanal hergestellt, also eine direkte und bleibende verbindung.

    Ein UDP Server zB. empfängt daten ohne darauf vorbereitet zu sein.
    Aber ein TCP Socket ist immer darauf vorbereitet.
    Das ganze merkt man auch wenn man sich den Script eines TCP Server mal anschaut. ( siehe unten im howto server programmieren )
    -Als Erstes muss das Socket aufgestellt werden
    -Dann Müssen in der Endlos-Schleife alle einkommenden verbindungen angenommen ewrden, bevor diese alle daten senden können.
    -Und nach der annahme kann der Server erst vom Client Socket daten empfangen.

    Also man merkt dass beim TCP erst eine Stabile VErbindung erstehen muss bevor daten ausgetauscht werden können, dass ist aber auch besser da der TCP Server dann weiß mit wem er es da zu tuhen hat ohne ip und des gleichen zu überprüfen.

    Zum vergleich, hier der Aufbau eines Chat-Systems, einmal TCP und einmal UDP

    TCP:
    -Server Socket steht

    ->Client wird am anderen PC vom User gestartet
    -User gibt daten ein und klickt auf "Verbinden"
    ->Client verbinded zum Server

    -<Server Akzeptiert Client

    -Kanal ist nun hergestellt ( Verbindung hergestellt )

    ->Client senden nun Daten

    -<Server empfängt daten
    -<Server speichert daten des Clients und setzt den user auf Online
    -<Server Registriert User alle Informationen sind gespeichert

    - User startet Chat miit anderem USer
    ->Client sended Chat Partner ID an Server

    -<Server kennt beide User und stellt nur noch den Chat ein

    - User können chatten

    und jetzt das nochmal mit UDP:

    -Server Socket steht

    ->Client wird am anderen PC vom User gestartet
    -User gibt daten ein und klickt auf "Verbinden"
    ->Client Sendet Daten direkt an Server

    -<Server bestätigt Daten und sendet ein paar Informationen

    - User startet Chat mit anderem User

    ->Client Sended ganze Zeit Username,PAssword und dann die ChatPartner ID und dann noch die Nachricht zum Server

    -User könnte etwas beschwerter chatten da der Client mehr CPU verbraucht für den PING der alle 10sec an den Server gesended wird damit der Server weiß dass der User Oline ist

    Ihr merkt dass der TCP Server Intiligenter ist und alles schneller abläuft.
    Durch den Virtuellen kanal merkt der Serevr wenn der Client plötzlich offline geht.
    zB. wenn beim User der PC abstürtzt oder der Strom ausfällt ^^
    Und der Chat Client nicht den Disconnect Command sendet.

    ICh hoffe ihr habt verstanden was ich mit all den Beispielen sagen möchte und was TCP eigentlich ist und was UDP ist ^^
    Denn beide werden von AutoIT angeboten =3

    Serverprogrammierung in AutoIT


    Also liebe AutoIT Fans,
    in diesem How-To werde ich euch zeigen wie ihr euch ganz einfach einen Server Programmieren könnt und dazu noch einen Client.
    Es handelt sich hier nur um Text-Nachrichten die zwischen den beiden ausgetauscht werden.
    Aber ihr könnt es als Grundstruktur verwenden und ganz eigene Dinge drauß machen

    Na egal wieder zurück zur Sache.
    Letzt Start

    Als erstes erstellst du einen neuen Script und nennst ihn "MyFirstServer.au3".
    Dann öffnest du den script durch Rechtsklick ->> Edit Script.
    Danach öffnet sic SciTE, der Editor, und du siehst schon ein paar inge in grün.
    Dies sind Kommentare.
    Es gibt Komentare die mit ";" anfangen und für Mehrzeilige Komentare gibt es "#cs" und "#ce" / #comments-start" und #comments-end", beides geht und ist das gleiche.
    Also du kannst die schon vorgegebenen Komentare ignorieren, ausfüllen oder wie ich es mache, sie einfach löschen^^. Das nervt halt nur!

    Nachdem alles nervige weg ist kannst du mit dem Server beginnen.
    Dein Server wird am Ende als Konsole ausgeführt, also kein Fenster und beim compilieren darauf achten , dass der Script als CUI compiliert wird!

    Das erste was du eingibst ist :
    Code:

    [autoit]


    TCPStartup()

    [/autoit]

    Damit wird die TCP Libary gestartet und du kannst TCP in deinem Script verwenden. (Ohne DLL oder so, AutoIT ist halt Betriebssystem abhängig)

    Dann, damit du auch ein Socket hast wo dich Clientprogramme kontaktieren können :
    Code:

    [autoit]


    $MainSocket = TCPListen("127.0.0.1",3000,100)
    ;Also der Server läuft auf der IP : 127.0.0.1 (localhost) und der Port ist 3000.
    ;Die 100 am Ende steht dafür das maximal 100 Clients angenommen werden.
    ;Natürlich könnt ihr alle Angaben frei ändern.

    [/autoit]

    Dann, damit dein Script nicht direkt nachdem u ihn gestartet hast wieder ausgeht.
    Eine Endlose Schleife :
    Code:

    [autoit]


    while 1
    wend

    [/autoit]


    So jetzt ist dein Script endlos.

    Nur kann er nichts empfangen und ist so so gut wie nutzlos.

    Damit er was empfangen kann und überhaupt Verbindungen annehmen kann ist eine neue Funktion fällig^^...
    Als erstes :
    Code:

    [autoit]


    $NewSocket = TCPAccept($MainSocket)

    [/autoit]


    und zum empfangen der angenommenen Verbindungen :
    Code:

    [autoit]


    TCPRecv($NewSocket,2048)
    ;er empfingt daten von dem $NewSocket also neu angenommenen Verbindungen
    ;er empfängt die Nachrichten (egal ob Daten oder sonst was) mit bis zu 2048kb/s

    [/autoit]


    Nun damit dein Script dies auch Intilligent ausführen kan und vielleicht noch eine von dier erstellte Funktion ausführt wenn Daten empfangen wurden (zB. sie Verarbeiten wenn du geheime Nachrichten sendest^^), musst du dies alles in die eindlose schleife einbauen.

    Also das sieht dann so aus :

    Code:

    [autoit]


    While 1
    $NewSocket = TCPAccept($MainSocket)

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

    If $NewSocket >= 0 Then
    Do
    $Recv = TCPRecv($NewSocket,2048)
    ;er empfingt daten von dem $NewSocket also neu angenommenen Verbindungen
    ;er empfängt die Nachrichten (egal ob Daten oder sonst was) mit bis zu 2048kb/s
    Until $Recv <> ""
    ;er empfängt daten bis er was empfangen hat das nicht "" ist, sprich das nicht gar nix ist^^
    ConsoleWrite("Empfangen : " & $Recv)
    ;hier könntest du noch deine eigenen Funktionen einbauan :D

    EndIf

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

    WEnd

    [/autoit]


    Also ihr seht es geht ganz einfach und ihr könnt damit kleine update Tools, minigame wie pennergame oder so, chat-sys, daten-transfer proggy, sowas wie teamviewer ^^, usw... erstellen.

    CLIENT

    Also dann machen wir ma den Client^^...
    Er ist im grunde ganz simpel und verbraucht nur 3 Zeilen für das Senden der Daten^^...
    aber es muss ja noch ein system rein^^....

    Na dann lasst uns anfangen xD...

    Als erstes,
    neben der MyFirstServer.au3 eine neue .au3 Datei erstellen.
    Du nennst sie "MyFirstClient.au3" .
    Dann öffnest du sie wie bei dem Server,
    und zu den Kommentaren hab ich oben ja noch was gesagt.
    Dann, als erstes benötigst du ein Include:
    Code:

    [autoit]


    #include <GuiConstants.au3>

    [/autoit]


    In der GuiConstants.au3 sind verschiedene Variablen deklariert (benannt).
    Eigentlich benötigst du nur eine Dieser Variablen^^...
    Aber nimm einfach das Include.

    Danach als nächstes, schreibst du den ersten TCP-Befehl rein:
    Code:

    [autoit]


    TCPStartUp()

    [/autoit]


    Dazu hab ich ja oben auch was geschrieben.

    Dann benötigst du ein GUI - Graphical User Interface -
    (Bei dem Server hast du ein CUI - Console User Inferface - benutzt)
    Code:

    [autoit]


    $GUI = GuiCreate("MeinErsterClient",300,500)
    ;Dieses GUI hat folgende Größenwerte : 300x500
    ;Also 300 - Breit und 500 - Hoch

    [/autoit]

    Noch zu dem GUI benötigst du ein Textfeld,
    und einen Button mit dem du die Nachrichten verschicken kannst.
    Code:

    [autoit]


    $Edit = GUICtrlCreateEdit("",0,0,300,200)
    ;Das Editfeld klebt an den Kanten des Fensters
    ;Und ist auch so breit wie das Fenster
    $OK = GUICtrlCreateButton("Senden",100,300,100,30)
    ;Auf diesem Button steht danach : Senden
    ;Der Button Hat folgende Position : 100│300 (x 100 & y 300)
    ;Der Button hat folgende Größenwerte : 100x30

    [/autoit]


    Damit aber dies alles angezeigt wird,
    wird ein kleiner aber wichtiger Befehl benötigt.
    Code:

    [autoit]


    GUISetState()
    ;sorgt dafür, dass das GUI das am nächsten ist
    ;angezeigt wird.

    [/autoit]


    Und damit dein Fenster, nicht gleich nachdem es geöffnet wurde, wieder ausgeht:
    Code:

    [autoit]


    While 1

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

    ;eine Endlose Schleife

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

    Wend

    [/autoit]


    Jetzt wird alles in deinem Fenster angezeigt,
    nur es passiert nichts wenn du auf "Send" klickst,
    und das Fenster schließt sich auch nicht.

    Dafür musst du die ganzen Funktionen in den Script einbauen,
    am besten in die endlose Schleife.
    Und jetzt wird auch endlich mal eine Variable aus dem Include benutzt.
    Diese Variable heißt "$GUI_EVENT_CLOSE"
    Code:

    [autoit]


    While 1
    $msg = GUIGetMsg()
    ; sorgt dafür, dass dein Script merkt
    ;wenn irgendwas angeklickt/ausgewählt wurde.
    Switch $msg
    ;damit du nicht immer vor case "$msg setzen musst
    Case $OK
    $MainSocket = TCPConnect("127.0.0.1","3000")
    ;Verbindet mit dem Server
    ;der unter der IP 127.0.0.1 (localhost)
    ;und unter dem PORT 3000 läuft
    TCPSend($MainSocket,GUICtrlRead($Edit))
    ;Sendet den Text im Textfeld an den Server
    MsgBox(0,"GESENDET","Die Nachricht wurde gesendet")
    WEnd

    [/autoit]


    Und das war auch schon ein Client der Daten sendet (aber keine empfängt )
    Damit euer Client Daten empfängt könnt ihr ja einen mix aus dem Server und dem Client machen.
    Das ist nicht so schwer und man lernt dazu....
    Und außerdem merkt euer Script nicht wenn ein Fehler beim Senden auftritt
    das könnt ihr bestimmt auch selber einfügen.

    Ich guck ma, wenn ich noch Zeit und Motivation finde werde ich den Client und Server verbessern^^.

    >>DATEIEN SENDEN

    Ich mach jetzt einfach Code rein^^..
    Das is scho ales fertig ihr könnt es umändrn und rumprobieren,
    aber bitte lasst die creditz von mir drinn und schreibt euren Namen unter
    "Moddet by :"
    rein..

    Code:

    [autoit]


    #cs ----------------------------------------------------------------------------

    AutoIt Version: 3.3.0.0
    Author: Jiyan Akgül --> Bitte so lassen

    Moddet by : Dein Name <<-- Dein Name

    Script Function:

    <>--Data Send Server--<>

    #ce ----------------------------------------------------------------------------

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

    ; Script Start -

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

    #cs
    Das müsst ihr dann in den script einbauan und anpassen
    #ce

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

    ;==== SERVER ====;

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

    #include <INet.au3>

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

    TCPStartup()

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

    Global $IP = _GetIP() ; ermittelt über DynDNS die IP
    Global $PORT = 4949
    Global $MaxLen = 2048 ;Maximale Speed die benutzt werden darf (ACHTUNG: BENUTZT BEI ZU VIEL DIE GANZE LEITUNG)

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

    $MainSocket = TCPListen($IP, $PORT, 1)

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

    MsgBox(64, "INFO", "Es gibt folgende DreiSchritte:" & @CR & "1.Datei Auswählen" & @CR & "2.Verbindung zum Cient herstellen" & @CR & "3.Datei senden")

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

    $File = FileOpenDialog("Bitte wählen sie die Datei aus", @DesktopDir, "All (*.*)")

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

    Do
    $NewSocket = TCPAccept($MainSocket)
    Until $NewSocket >= 0
    TCPSend($NewSocket, "0x" & StringToBinary("DATEI"))
    TCPSend($NewSocket, "0x" & Hex(StringLen(FileGetLongName($File))) & StringToBinary(FileGetLongName($File)))
    TCPSend($NewSocket, "0x" & Hex(FileGetSize($File)))
    Do
    $get = TCPRecv($NewSocket, $MaxLen)
    Until $get <> ""

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

    If $get = "0x"&Hex(2)&BinaryToString("OK") Then
    MsgBox(64,"INFO","Datei wurde von Gegenstelle angenommen")
    TCPSend($NewSocket,$File)
    MsgBox(64,"INFO","Die Datei wurde gesendet")

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

    ElseIf $get = "0x"&Hex(2)&BinaryToString("NO") Then
    MsgBox(64,"INFO","Datei wurde von Gegenstelle angenommen")
    TCPCloseSocket($NewSocket)
    TCPCloseSocket($MainSocket)
    TCPShutdown()
    Exit
    EndIf

    [/autoit]


    Code:

    [autoit]


    #cs ----------------------------------------------------------------------------

    AutoIt Version: 3.3.0.0
    Author: Jiyan Akgül --> Bitte so lassen

    Moddet by : Dein Name <<-- Dein Name

    Script Function:

    <>--Data Send Server--<>

    #ce ----------------------------------------------------------------------------

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

    ; Script Start -

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

    #cs
    Das müsst ihr dann in den script einbauan und anpassen
    #ce

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

    ;==== CLIENT ====;

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

    Global $IP = IniRead(@ScriptDir & "\options.ini", "Connection", "IP", "127.0.0.1") ;IP wird aus der ini gelesen
    Global $Port = IniRead(@ScriptDir & "\options.ini", "Connection", "Port", "4949") ;Port wird aus der ini gelesen
    Global $MaxLen = IniRead(@ScriptDir & "\options.ini", "Connection", "MaxLen", "2048") ;Maximale Bitrate wird aus der ini gelesen

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

    TCPStartup()

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

    $Connect = MsgBox(0x21, "INFO", "Mit Server verbinden?")
    If $Connect = 2 Then
    TCPShutdown()
    Exit
    EndIf

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

    MsgBox(0x40, "INFO", "Verbinde nun mit Server")

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

    _connect()

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

    Func _connect()
    $MainSocket = TCPConnect($IP, $Port)
    If $MainSocket = @error Then
    $Error = MsgBox(0x15,"ERROR","Konnte nicht mit Server verbinden."&@CR&"Bitte überprüfen Sie die Einstellungen."&@CR&"Noch einmal versuchen?")
    if $Error = 2 Then
    TCPCloseSocket($MainSocket)
    TCPShutdown()
    Exit
    ElseIf $Error = 4
    TCPCloseSocket($MainSocket)
    _connect()
    EndIf
    EndIf
    Do
    $get = TCPRecv($MainSocket,$MaxLen)
    Until $get <> ""

    Do
    $get_FileName = TCPRecv($MainSocket,$MaxLen)
    Until $get_FileName <> ""
    $FileName = BinaryToString(StringRight($get_FileName,Dec(StringLeft($get_FileName,10))))
    Do
    $get_FileSize = TCPRecv($MainSocket,$MaxLen)
    Until $get_FileSize <> ""
    $FileSize = Dec(StringLeft($get_FileSize,10))
    If $get = "0x" & StringToBinary("DATEI") Then
    $yes_no = MsgBox(0x44,"INFO","Der Server möchte eine Datei senden."&@CR&"Name : "&$FileName&@CR&"Größe : "&$FileSize&@CR&"Annehmen?")
    if $yes_no = 6 Then
    TCPSend($MainSocket,"0x"&Hex(2)&BinaryToString("OK"))
    $File = FileSaveDialog("Datei speichern als",@DesktopDir,"Alle (*.*)")
    $open = FileOpen($File,2)
    FileWrite($open,TCPRecv($MainSocket,$MaxLen))
    FileClose($open)
    MsgBox(0x40,"INFO","Datei wurde empfangen")
    Run("explorer.exe /"&StringReplace($File,$FileName,""))
    ElseIf $yes_no = 7 Then
    TCPSend($MainSocket,"0x"&Hex(2)&BinaryToString("NO")
    TCPCloseSocket($MainSocket)
    TCPShutdown()
    Exit
    EndIf
    EndIf

    [/autoit]

    ; NICHT DAS THANKS VERGESSEN x)

    EndFunc ;==>_connect