Einführung in TCP
ICh red net gern übern heißen brei also fangen wa glei 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,Pssswort 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 und UPD eigentlich sind.
Denn beide Protokolle werden von AutoIT unterstützt.
Serverprogrammierung in AutoIT
Als erstes erstellst du einen neuen Script und nennst es "MyFirstServer.au3".
Dann öffnest du das script durch Rechtsklick ->> Edit Script.
Danach öffnet sich SciTE, der Editor, und du siehst schon ein paar Dinge 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".
Also du kannst die schon vorgegebenen Komentare ignorieren, ausfüllen oder wie ich es mache, sie einfach löschen.
Dein Server wird am Ende als Konsole ausgeführt, also es gibt kein Fenster.
Also nachher beim compilieren darauf achten , dass das Script als CUI compiliert wird!
Das erste was du eingibst ist :
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 :
Eine Endlose Schleife :
So jetzt ist dein Script endlos.
Nur kann er jetzt noch nichts empfangen und ist so gut wie nutzlos.
Damit er was empfangen kann und überhaupt Verbindungen annehmen kann ist eine neue Funktion nötig.
Als erstes :
und zum empfangen der angenommenen Verbindungen :
Also das sieht dann so aus :
Quellcode
- While 1
- $NewSocket = TCPAccept($MainSocket)
- If $NewSocket >= 0 Then
- Do
- $Recv = TCPRecv($NewSocket,2048)
- ;er empfängt 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 einbauen, die Daten sind in $Recv drin.
- EndIf
- WEnd
CLIENT
Als erstes,
neben der MyFirstServer.au3 eine neue .au3 Datei erstellen.
Du nennst sie "MyFirstClient.au3" .
Dann öffnest du sie wie bei dem Server,
Dann, als erstes benötigst du ein Include:
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:
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)
Quellcode
- $GUI = GuiCreate("MeinErsterClient",300,500)
- ;Dieses GUI hat folgende Größenwerte : 300x500
- ;Also 300 - Breit und 500 - Hoch
- [code]
- Zu dem GUI benötigst du noch ein Textfeld, und einen Button mit dem das Senden ausgelöst wird.
- [code]
- $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
wird ein kleiner aber wichtiger Befehl benötigt.
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"
Quellcode
- 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
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 außerdem merkt euer Script nicht wenn ein Fehler beim Senden auftritt,
dass könnt ihr bestimmt auch selber einfügen.
>>DATEIEN SENDEN
Ich mach jetzt einfach den Code direkt rein
C-Quellcode
- #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 ----------------------------------------------------------------------------
- ; Script Start -
- #cs
- Das müsst ihr dann in den script einbauan und anpassen
- #ce
- ;==== SERVER ====;
- #include <INet.au3>
- TCPStartup()
- 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)
- $MainSocket = TCPListen($IP, $PORT, 1)
- MsgBox(64, "INFO", "Es gibt folgende DreiSchritte:" & @CR & "1.Datei Auswählen" & @CR & "2.Verbindung zum Cient herstellen" & @CR & "3.Datei senden")
- $File = FileOpenDialog("Bitte wählen sie die Datei aus", @DesktopDir, "All (*.*)")
- 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 <> ""
- 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")
- ElseIf $get = "0x"&Hex(2)&BinaryToString("NO") Then
- MsgBox(64,"INFO","Datei wurde von Gegenstelle angenommen")
- TCPCloseSocket($NewSocket)
- TCPCloseSocket($MainSocket)
- TCPShutdown()
- Exit
- EndIf
Brainfuck-Quellcode
- #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 ----------------------------------------------------------------------------
- ; Script Start -
- #cs
- Das müsst ihr dann in den script einbauan und anpassen
- #ce
- ;==== CLIENT ====;
- 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
- TCPStartup()
- $Connect = MsgBox(0x21, "INFO", "Mit Server verbinden?")
- If $Connect = 2 Then
- TCPShutdown()
- Exit
- EndIf
- MsgBox(0x40, "INFO", "Verbinde nun mit Server")
- _connect()
- 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
- EndFunc ;==>_connect
gez :: *electriZer*
(C) 2009-2012 by Jiyan Akgül