ChatServer. Unser Server



Ähnliche Dokumente
Wie halte ich Ordnung auf meiner Festplatte?

Professionelle Seminare im Bereich MS-Office

Objektorientierte Programmierung

Ein Hinweis vorab: Mailkonfiguration am Beispiel von Thunderbird

Mein Computerheft. www. Internet. Name:

Der Kalender im ipad

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster

Meet the Germans. Lerntipp zur Schulung der Fertigkeit des Sprechens. Lerntipp und Redemittel zur Präsentation oder einen Vortrag halten

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

mysql - Clients MySQL - Abfragen eine serverbasierenden Datenbank

Anwendungsbeispiele Buchhaltung

Zwischenablage (Bilder, Texte,...)

Urlaubsregel in David

Beschreibung Regeln z.b. Abwesenheitsmeldung und Weiterleitung

-Versand an Galileo Kundenstamm. Galileo / Outlook

Facebook erstellen und Einstellungen

TeamSpeak3 Einrichten

40-Tage-Wunder- Kurs. Umarme, was Du nicht ändern kannst.

Informatik Kurs Simulation. Hilfe für den Consideo Modeler

Leichte-Sprache-Bilder

OP-LOG

Handbuch für Easy Mail in Leicht Lesen

Spiel und Spaß im Freien. Arbeitsblat. Arbeitsblatt 1. Zeichnung: Gisela Specht. Diese Vorlage darf für den Unterricht fotokopiert werden.

UserManual. Handbuch zur Konfiguration einer FRITZ!Box. Autor: Version: Hansruedi Steiner 2.0, November 2014

1. Loggen Sie sich mit Ihrem Benutzernamen in den Hosting-Manager (Confixx) auf Ihrer entsprechenden AREA ein.

FuxMedia Programm im Netzwerk einrichten am Beispiel von Windows 7

teamsync Kurzanleitung

Internationales Altkatholisches Laienforum

Fotostammtisch-Schaumburg

1 topologisches Sortieren

Inhaltsverzeichnis. 1. Empfängerübersicht / Empfänger hinzufügen 2. Erstellen eines neuen Newsletters / Mailings 3. Versand eines Newsletters

Mit einem Doppelclick auf den Ortsnamen erhalten Sie eine Liste mit allen Pulheimer Adressen angezeigt.

Was meinen die Leute eigentlich mit: Grexit?

Sich einen eigenen Blog anzulegen, ist gar nicht so schwer. Es gibt verschiedene Anbieter. ist einer davon.

Einrichten eines Postfachs mit Outlook Express / Outlook bis Version 2000

Programme im Griff Was bringt Ihnen dieses Kapitel?

Das Festkomitee hat die Abi-Seite neu konzipiert, die nun auf einem (gemieteten) Share Point Server

Sie können diesen Service verwenden, um fast beliebig große Dateien auch über 2 GB zu versenden.

Das Leitbild vom Verein WIR

Computeria Rorschach Mit Excel Diagramme erstellen

Dieser Ablauf soll eine Hilfe für die tägliche Arbeit mit der SMS Bestätigung im Millennium darstellen.

Installation Hardlockserver-Dongle

Tutorial -

Was ist Sozial-Raum-Orientierung?

Erstellen einer digitalen Signatur für Adobe-Formulare

Schrittweise Anleitung zur Erstellung einer Angebotseite 1. In Ihrem Dashboard klicken Sie auf Neu anlegen, um eine neue Seite zu erstellen.

KVIrc installieren (win) i. KVIrc installieren (win)

Dokumentation für das Spiel Pong

Wir machen neue Politik für Baden-Württemberg

Anwendungsbeispiele Buchhaltung

Bauteilattribute als Sachdaten anzeigen

Einstellungen im Internet-Explorer (IE) (Stand 11/2013) für die Arbeit mit IOS2000 und DIALOG

So funktioniert das online-bestellsystem GIMA-direkt

Virtueller Seminarordner Anleitung für die Dozentinnen und Dozenten

Infinigate (Schweiz) AG. Secure Guest Access. - Handout -

Kurzanleitung SEPPmail

Das sogenannte Beamen ist auch in EEP möglich ohne das Zusatzprogramm Beamer. Zwar etwas umständlicher aber es funktioniert

STRATO Mail Einrichtung Mozilla Thunderbird

Erklärung zu den Internet-Seiten von

Lernerfolge sichern - Ein wichtiger Beitrag zu mehr Motivation

Microsoft PowerPoint 2013 Folien gemeinsam nutzen

Herzlich Willkommen bei der nfon GmbH

Anleitung über den Umgang mit Schildern

Version smarter mobile(zu finden unter Einstellungen, Siehe Bild) : Gerät/Typ(z.B. Panasonic Toughbook, Ipad Air, Handy Samsung S1):

MOM - Medienforum Online-Medien Anleitung zum Ändern der Login-Nummer und des Passworts

Benutzername: Passwort: Nun befindest du dich in einem Bereich, von wo aus du Berichte über Ereignisse schreiben kannst und Fotos dazugeben kannst.

Erstellen einer PostScript-Datei unter Windows XP

ONLINE-AKADEMIE. "Diplomierter NLP Anwender für Schule und Unterricht" Ziele

Anleitung zum Upgrade auf SFirm Datenübernahme

Einrichtung des Cisco VPN Clients (IPSEC) in Windows7

Windows. Workshop Internet-Explorer: Arbeiten mit Favoriten, Teil 1

Primzahlen und RSA-Verschlüsselung

How to install freesshd

Wenn wir also versuchen auf einen anderen PC zuzugreifen, dann können wir sowohl per Name als auch mit der Adresse suchen.

Anleitung zum Upgrade auf SFirm 3.x + Datenübernahme. I. Vorbereitungen

Anleitung: Sammel-Rechnungen für Lizenzen bei Swiss Basketball

Windows 7: Neue Funktionen im praktischen Einsatz - Die neue Taskleiste nutzen

LANiS Mailversender ( Version 1.2 September 2006)

Sie finden im Folgenden drei Anleitungen, wie Sie sich mit dem Server der Schule verbinden können:

Erstellen einer Collage. Zuerst ein leeres Dokument erzeugen, auf dem alle anderen Bilder zusammengefügt werden sollen (über [Datei] > [Neu])

Kurzanleitung MAN E-Learning (WBT)

Virtual Private Network

STRATO Mail Einrichtung Android 4.4

Lieber SPAMRobin -Kunde!

Über die Internetseite Hier werden unter Download/aktuelle Versionen die verschiedenen Module als zip-dateien bereitgestellt.

Herzlich Willkommen bei der BITel!

Geld Verdienen im Internet leicht gemacht

Kopfzeile. Inhaltsverzeichnis

Step by Step Remotedesktopfreigabe unter Windows Server von Christian Bartl

Alle Schlüssel-Karten (blaue Rückseite) werden den Schlüssel-Farben nach sortiert und in vier getrennte Stapel mit der Bildseite nach oben gelegt.

Einrichten von Pegasus Mail zur Verwendung von MS Exchange und Übertragen der alten Maildaten auf den neuen Server

Internet-Wissen. Browser:

Publizieren von Webs mit SmartFTP

Gruppenrichtlinien und Softwareverteilung

Thema Stichwort Programm Letzte Anpassung Serienbrief erstellen Ablauf

Anleitung zur Nutzung des SharePort Utility

In diesem Tutorial lernen Sie, wie Sie einen Termin erfassen und verschiedene Einstellungen zu einem Termin vornehmen können.

ACDSee 2009 Tutorials: Rote-Augen-Korrektur

Handbuch Fischertechnik-Einzelteiltabelle V3.7.3

Transkript:

ChatServer Wir wollen einen universell verwendbaren Server programmieren, der die wichtigsten Funktionen eines Chat-Servers erfüllt: es soll ein 'Threaded TCP Server' sein Clients können sich mit Port Nummer (änderbar) 5000 anmelden die Clients werden einzeln begrüßt sie können sich mit einem Spezialkommando '/quit' wieder abmelden Die wichtigste Funktion: Jede Eingabezeile eines Clients wird an alle Clients weiterverbreitet. Erweiterungen, die wir im Auge behalten: bei der Anmeldung wählt der Client einen Namen (Nickname), der in der Konversation verwendet wird durch ein Spezialkommando kann man nur einem einzigen anderen Client etwas mitteilen ('flüstern', eventuell mittels [Name] Text) Du siehst, die Erweiterungen betreffen die Art der Konversation und die Formulierung von Anforderungen das wird dann das 'Protokoll' unseres Chatraumes. Als Client kommt in Frage: ein simpler TCP Client, der nur in einer Endlosschleife liest und anzeigt (Welches Problem kann hier auftauchen kann dieses Programm gleichzeitig einlesen, senden und empfangen?) ein GUI-Programm, das ganz komfortabel ein Ausgabe-Textfenster und eine Eingabezeile besitzt ein beliebiges Telnet-Programm, wie es im Lieferumfang von Windows und Unix enthalten ist. (Beachte den Zeilenvorschub: "\n" versteht Python, ein Telnet-Programm mit VT-Emulation braucht aber wie Unix zumeist ein "\r\n" (return+newline)) Am besten programmieren wir unseren Client später so, dass er für das passende Zeilenendzeichen zur Ausgabe auf dem Bildschirm sorgt. Unser Server Ich möchte das Programm 'top-down' erklären, also von den großen Einheiten hinunter zu den kleinen. Zuerst die Importe von Bibliotheks-Modulen from threading import * from Queue import Queue import SocketServer threading enthält die Klasse Thread, die uns Methoden zur Parallel-Abarbeitung von Prozessen bereitstellt. Die einzelnen Anforderungen an den Server werden wir in Form einer Queue (FIFO- Warteschlange) zwischenspeichern, damit jeder Client seine Botschaften konfliktlos ablegen kann. Da mehrere Threads gleichzeitig auf diese Daten zugreifen können, müssen wir einen lock-release Mechanismus einbauen, damit nicht ein zweiter Thread Daten während ihrer Abarbeitung verändern Wolfgang Urban, HIB Wien 1

kann. Der lock sollte 'reentrant' sein (der selbe Programmteil kann mehrfach aufgerufen sein). Und SocketServer enthält bereits einen rudimentären TCP Server als praktische Klasse, den wir unseren Anforderungen anpassen werden. Der Aufruf unseres Servers: def start(port=5000): server = MyChatServer(('localhost',port),MyRequestHandler) print "Server started, waiting for connections." server.serve_forever() server.shutdown() print "Shut down!" start(5000) MyChatServer ist die oben erwähnte von uns angepasste Serverklasse, von der server eine Instanz darstellt. Die Metode serve_forever() lässt die Hauptschleife des Servers ewig laufen. Aber was soll unser Server eigentlich mit den Clients tun? Nun jeden in einem eigenen Thread behandeln. Und wie? Das teilen wir durch die Angabe eines Handlers mit MyRequestHandler wird als Klassenname übergeben, damit der Server dann für jeden ankommenden Client ein eigenes Objekt, das mit dieser Handler-Methode ausgestattet ist, erzeugen kann. Nun zur Definition von MyChatServer: class MyChatServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): allow_reuse_address = 1 def init (self,server_address,request_handler_class): SocketServer.TCPServer. init (self,server_address, request_handler_class) self.chatroom = ChatRoom() self.chatroom.setdaemon(1) self.chatroom.start() def shutdown(self): self.chatroom.shutdown() Wir leiten unseren Server natürlich von SocketServer.TCPServer ab. Die Behandlung der Clients soll durch ständiges Kontrollieren aller Verbindungen geschehen: ThreadingMixin. Die init-methode bereitet den TCP Server vor, übergibt unsere Adresse und die erwähnte Handler-Klasse. Was der Server in seiner Hauptschleife tun soll das Verteilen der Meldungen wollen wir nicht hier programmieren, sondern in einer eigenen Klasse. ChatRoom() soll sie heißen und als Thread laufen. Wolfgang Urban, HIB Wien 2

Nun fehlt noch die Handler-Klasse: class MyRequestHandler(SocketServer.StreamRequestHandler): def setup(self): SocketServer.StreamRequestHandler.setup(self) self.server.chatroom.addchatter(self.sendanswer) print "%s:%d connected" % self.client_address def finish(self): self.server.chatroom.removechatter(self.sendanswer) SocketServer.StreamRequestHandler.finish(self) print "%s:%d disconnected" % self.client_address def handle(self): self.sayhello() while 1: line = self.rfile.readline() if not line: line = line.strip() if line.upper().startswith("/quit"): if line.upper().startswith("/shutdown"): self.server.shutdown() if line!= "": message = ("<%s:%d> " % self.client_address)+line self.server.chatroom.spread(message) def sayhello(self): self.wfile.write("willkommen %s! Tippe '/quit' um auszusteigen!\r\n"% str(self.client_address)) def sendanswer(self,msg): self.wfile.write(msg+'\r\n') setup und finish überschreiben die Originalmethoden und sollen dem Server das Ankommen bzw. das Abmelden eines Clients mitteilen. handle ist nun die eigentliche Bearbeitungsroutine. Am Anfang begrüßen wir den neuen Chat-Gast und erklären die wichtigsten Dinge. Dann gehen wir in eine Endlosschleife, wo wir mit rfile den Socket wartend auslesen wir warten auf eine Textzeile dieses Chatters. wenn 'nichts' zurückkommt ist die Verbindung unterbrochen und wir beenden die Schleife dann testen wir auf Spezialkommandos und andernfalls basteln wir uns eine Zeile zusammen, die den Schreiber dieser Zeile und den Inhalt darstellt. (Hier wäre ein Nickname praktisch). self.server.chatroom.spread(message) ist die Verbindung zu den Chatroom- Funktionen. Auf diese Weise wird der Befehl zum Verteilen der Botschaft an die Chat- Teilnehmer erteilt. eine zentrale Rolle spielt die Methode sendanswer. Sie ist die Nabelschnur, mit der unser Server den Client erreichen kann. Bei addchatter übergeben wir auch genau die Adresse Wolfgang Urban, HIB Wien 3

dieser Funktion. Will der Server dem Chatter etwas schicken, braucht er nur diese Methode aufzurufen. Da sie also den Chat-Teilnehmer aus Sicht des Servers vollständig repräsentiert, nennen wir diese Methode dann im Chatroom chatter. (Eingaben vom Client zum Server muss nicht der Server entschlüsseln: unser Handler untersucht die Eingabezeile und leitet nötigenfalls selbst die Server-Aktivität wie etwa addchatter oder removechatter ein.) Und jetzt nur mehr die Funktionen des Chatrooms: class ChatRoom(Thread): def init (self): Thread. init (self) self.events = Queue() self.messages = Queue() self.chatters = [] self.chatters_lock = RLock() self._shutdown = 0 events sind Ereignisse, die der Server bearbeiten soll. messages sind die zugehörigen Botschaften, die an die Clients verschickt werden sollten. chatters ist die Liste aller aktiver Teilnehmer tatsächlich ist es aber die Liste der entsprechenden sendanswer Methoden. chatters_lock ist der Lock, den wir zum Ansprechen von Daten verwenden, die im Hintergrund ständig verändert werden könnten. Eine Methode zum Schließen des Chatrooms könnte man vorbereiten: def shutdown(self): self._shutdown = 1 print "shutdown requested!" self.messages.put("server is shutting down!") self.events.put("/shutdown") Die folgenden beiden Funktionen nehmen einen neuen Client in die Liste auf, bzw. entfernen ihn daraus. def addchatter(self,chatter): self.chatters.append(chatter) pass def removechatter(self,chatter): self.chatters.remove(chatter) pass Nun die Hauptschleife des Threads. Wir warten ständig auf Ereignisse und liefern Botschaften an alle Teilnehmer. Für spezielle Zusatzfunktionen ('Flüstern',...) müssten wir hier oder in delivermessage weiterprogrammieren. def run(self): while 1: self.waitforevent() Wolfgang Urban, HIB Wien 4

if self._shutdown: if self.messages.qsize()>0: self.delivermessage() spread erzeugt ein Ereignis und legt den Text in der Queue ab. Diese Methode wird vom Client-Handler aufgerufen! def spread(self,msg): self.messages.put(msg) self.events.put("message: "+msg) Warte auf das Eintreffen eines Events in der Warteschlange: def waitforevent(self): nextevent = self.events.get() print nextevent return Die folgende Methode versucht, eine Botschaft aus der Queue an alle (augenblicklich aktiven) Teilnehmer zu verteilen. def delivermessage(self): msg = self.messages.get_nowait() except Queue.Empty: return chatters_copy = self.chatters[:] chatters_copy = [] for chatter in chatters_copy: self.sendtochatter(chatter,msg) Und die letzte Methode führt die Versendung für einen Client tatsächlich durch, indem sie chatter, was ja nichts anderes als sendanswer eines Clients ist, aufruft. Falls ein Client nicht mehr erreichbar ist, löschen wir ihn aus der Liste. def sendtochatter(self,chatter,msg): chatter(msg) self.removechatter(chatter) Wie wir nun einen passenden eleganten Chat-Client programmieren können, soll ein weiteres Kapitel sein. Wolfgang Urban, HIB Wien 5