Tutorial
Netzwerkprogrammierung mit TSNE_V3
von ThePuppetMaster | Seite 4 von 8 |
TSNE ist ein "Ereignis-orientiertes" Modul. Das bedeutet, dass TSNE quasi eigenständig arbeitet und bei einem Ereignis eine Funktion aufruft.
Ereignisse sind hierbei das Empfangen neuer Daten oder eine Zustandsänderung eines Sockets.
Angenommen wir erzeugten ein Client-Socket, das eine Verbindung zu Google herstellt und dessen HTML-Seite herunterladen soll. Gehen wir des Weiteren davon aus, dass die Verbindung erfolgreich hergestellt wurde und wir dem Google-Server mitgeteilt haben, was wir von ihm wollen. Nachdem der Google-Server die Antwort erzeugt hat, sendet er diese Daten an uns zurück. Datei erfolgt die Übermittlung der Daten in ca. 8 KByte langen Blöcken. Wenn TSNE nun einen Block empfangen hat, dann muss dies dem Programm mitgeteilt werden. Dies geschieht über sogenannte Callbacks (vgl. Wikipedia-Artikel: Rückruffunktion).
Mit dem Konzept von Callback-Funktionen lässt sich zur Laufzeit eine Funktion festlegen, die aufgerufen werden soll. Dem aufrufenden Code muss die Funktion nicht namentlich bekannt sein. Vereinfacht dargestellt ist das Besondere bei Callback-Funktionen, dass die Funktion, die aufgerufen werden soll, in einer Variable steht, sodass ihr Aufruf im Quelltext nicht fest vorgegeben sein muss:
'Pseudocode
FUNCTION A
PRINT "Hallo Welt!"
END FUNCTION
FUNCTION B
PRINT "Das ist ein Test."
END FUNCTION
FUNCTION C
PRINT "Lorem Ipsum."
END FUNCTION
SUB GibIrgendwasOftAus (WelcheSchriftzugFunction)
FOR i = 1 TO 5
RufFunktionAuf: WelcheSchriftzugFunction
NEXT i
END SUB
DIM Funktionsliste(1 To 3)
Funktionsliste(1) = @A 'Zeiger auf FUNCTION A
Funktionsliste(2) = @B 'Zeiger auf FUNCTION B
Funktionsliste(3) = @C 'Zeiger auf FUNCTION C
DO
Schriftzugsfunktion = Zufallszahl(1<=x<=3)
GibIrgendwasOftAus ( Funktionsliste(Schriftzugsfunktion) )
SLEEP
LOOP
Erklärung zum Pseudocode:
Im Array Funktionsliste sind Zeiger auf 3 FUNCTIONs gespeichert. Funktionen können nicht nur durch ihren Namen (A, B oder C im Beispiel oben), sondern auch durch eben diesen Zeiger aufgerufen werden. In der DO-Schleife wird per Zufall bestimmt, welcher Funktionszeiger aus dem Array gewählt werden soll. Dieser per Zufall ausgesuchte Funktionszeiger wird dann an die aufrufende Funktion (GibIrgendwasOftAus) übergeben. Diese ruft dann 5x die FUNCTION auf, die man ihr als Parameter übergeben hat. Die FUNCTION GibIrgendwasOftAus kann jede beliebige FUNCTION aufrufen, die man ihr als Parameter übergibt.
Zurück zur TSNE: Beim Aufruf einer "TSNE_Create_xxx" muss eine FUNCTION als Pointer mitgegeben werden.
Beim Erhalt eines Datenblocks vom Server (im Beispiel vom Google-Server) ruft TSNE nun diese mitgeteilte Funktion auf und übergibt dabei die Daten in einem Parameter. Die TSNE muss nicht wissen, wie die aufzurufende FUNCTION aussieht, wie sie heißt, was sie macht o.ä., sondern sie muss nur ihre "Anschrift", ihren Pointer haben, um sie bei Bedarf, also wenn Daten vorhanden sind, aufrufen zu können. So kann der Programmierer eine beliebige eigene FUNCTION an die TSNE übergeben und die TSNE wird sie, wenn das jeweilige Ereignis eintritt, ausführen - als Callbackfunktion - und zwar, ohne dass die FUNCTION des Programmierers in der TSNE-Include-Datei auch nur ein einziges Mal genannt werden müsste.
Dieses Verfahren wird auch bei Statusänderungen angewandt. Um das Ganze flexibel zu gestalten, gibt es für unterschiedliche Ereignisse unterschiedliche Callbacks, die entsprechend unterschiedliche Parameterwerte übergeben.
So ist es z.B. nicht nötig, dass beim Trennen einer Verbindung Daten übermittelt werden. Darum ist jedes Ereignis mit einem speziell aufgebauten Callback verknüpft.
Die Bezeichnung dieses Callbacks bzw. der Sub-Routinen-Name kann frei gewählt werden, genauso wie die Bezeichnung der Parameter. Jedoch müssen die Datentypen übereinstimmen und die Position der Variablen im Sub-Header.
Es existieren insgesamt 5 unterschiedliche Ereignisse:
- Disconnect: Dieses wird immer dann aufgerufen, wenn eine Client-Verbindung getrennt wurde. Hierbei ist es egal, ob die Trennung vom Programm oder von der Gegenstation aus erfolgte.
- Connected: Wurde eine Client-Verbindung vollständig aufgebaut, dann tritt dieses Ereignis ein. Es zeigt an, dass ab jetzt Daten übertragen oder Statusinformationen abgefragt werden können.
- NewData: Empfängt ein Socket neue Daten von der Gegenstelle, dann tritt dieses Ereignis ein.
- NewConnection: Bei Verwendung eines Server-Sockets signalisiert dieses Ereignis die Anfrage eines Verbindungsaufbaus zu uns.
- NewConnectionCanceled: Ist dasselbe Ereignis wie NewConnection. Der einzige Unterschied besteht darin, dass die Verbindung von TSNE automatisch abgelehnt wurde, da die anfragende Gegenstation auf einer (vom Programmierer festlegbaren) Sperrliste steht.
TSNE nutzt einen eigenen Haupt-Thread, welcher den Status aller Sockets überwacht, sowie jeweils einen eigenen Thread pro Socket, welcher den Status eines einzelnen Sockets sowie das NewData-Ereignis überwacht.
Zwar ist TSNE mit einem Constructor und Destructor ausgestattet; um aber zu verhindern, dass Sockets nach einem Programmende unkontrolliert weiter arbeiten, sollte man sich jedoch nicht auf die problemlose Funktion des Destructors verlassen, sondern selbst (vor dem Programmende) dafür sorgen, das alle Verbindungen beendet wurden..
In diesem Tutorial werden wir uns ausschließlich mit dem Aufbau, der Handhabung und Verwaltung von TCP-Verbindungen befassen. TSNE unterstützt zwar auch UDP-Verbindungen, aber aufgrund der im Internet und im lokalen Netzwerk vorherrschenden Verbreitung von TCP-Verbindungen beschränken wir uns hier auf diese Variante.
Zusätzliche Informationen und Funktionen | |||||||
---|---|---|---|---|---|---|---|
|
|