# Name: "Client1" : Client-Anwendung zur Didaktik der Socketprogrammierung # Autor: Marco Schneider, Gymnasium am Rittersberg, Kaiserslautern # Datum: 22.10.2009 # Version: 2.0 # Python: 3.1 # -*- coding: utf-8 -*- # model import asyncore, socket class Model(asyncore.dispatcher): def __init__(self, cbVerb, cbGetr, cbEmpf): asyncore.dispatcher.__init__(self) self.buffer = b'' self.Ausgabe = '' self.cbVerb = cbVerb self.cbGetr = cbGetr self.cbEmpf = cbEmpf def handle_connect(self): #print("connected") self.cbVerb() def handle_close(self): #print("closed") self.cbGetr() self.close() def handle_read(self): #print("lesen") ausg=str(self.recv(4096),encoding='utf8') if ausg != '': self.Ausgabe = ausg.replace("\r","") self.cbEmpf() def writable(self): return (len(self.buffer) > 0) def handle_write(self): #print("handle_write") sent = self.send(self.buffer) self.buffer = self.buffer[sent:] def cbVerb(self): pass def cbGetr(self): pass def cbEmpf(self): pass # view from tkinter import * class View(Tk): def __init__(self, cbVerbinde, cbSende, cbTrenne, cbHalt): Tk.__init__(self) # Callbacks self.cbVerbinde = cbVerbinde self.cbSende = cbSende self.cbTrenne = cbTrenne self.protocol("WM_DELETE_WINDOW",cbHalt) # cbHalt wird aufgerufen, wenn das 'X' gedrückt wird # Fenster self.title("Client 1") self.geometry('687x609') # Labels self.lEmpfangen = Label(master=self, text="empfangen", anchor=W, justify=LEFT) self.lEmpfangen.place(x=16, y=136, width=59, height=13) self.lAdresse = Label(master=self, text="Adresse", font=("Arial", 12), anchor=W, justify=LEFT) self.lAdresse.place(x=16, y=12, width=65, height=18) self.lremotePort = Label(master=self, text="Port", font=("Arial", 12), anchor=W, justify=LEFT) self.lremotePort.place(x=16, y=44, width=65, height=18) self.lzuSenden = Label(master=self, text="zu senden", anchor=W, justify=LEFT) self.lzuSenden.place(x=452, y=136, width=59, height=13) self.lMeldungen = Label(master=self, text="Meldungen", anchor=W, justify=LEFT) self.lMeldungen.place(x=16, y=488, width=59, height=13) self.lStatus = Label(master=self, text="", font=("Arial", 12, "bold"), fg="red", anchor=W, justify=LEFT) self.lStatus.place(x=210, y=72, width=100, height=25) # Entries self.eHost = Entry(master=self, background="white") self.eHost.place(x=88, y=8, width=121, height=21) self.eHost.insert(0,"www.hsg-kl.de") self.ePort = Entry(master=self, background="white") self.ePort.place(x=88, y=40, width=121, height=21) self.ePort.insert(0,"80") # Buttons self.bLoesche = Button(master=self, text="Ausgaben löschen") self.bLoesche.place(x=560, y=104, width=110, height=25) self.bVerbinde = Button(master=self, text="Verbinden") self.bVerbinde.bind('',self.cbVerbinde) self.bVerbinde.place(x=88, y=72, width=105, height=25) self.bSende = Button(master=self, text="Senden") self.bSende.bind('',self.cbSende) self.bSende.place(x=210, y=104, width=220, height=25) self.bSende.config(state='disabled') self.bTrenne = Button(master=self, text="Trennen") self.bTrenne.bind('',self.cbTrenne) self.bTrenne.place(x=88, y=104, width=105, height=25) self.bTrenne.config(state='disabled') # Textwidgets und Scrollbars self.tSenden = Text(master=self, background="white") self.tSenden.place(x=452, y=152, width=221, height=329) self.tSenden.insert(INSERT,'GET /abc.html HTTP1.1 \n') self.tSenden.insert(INSERT,'Host: www.hsg-kl.de \n') self.tSenden.insert(INSERT,'\n') self.scrollbar1 = Scrollbar(self.tSenden, orient=VERTICAL) self.tSenden.config(yscrollcommand=self.scrollbar1.set) self.scrollbar1.pack(side=RIGHT, fill=Y) self.scrollbar1.config(command=self.tSenden.yview) self.tEmpfangen = Text(master=self, background="white") self.tEmpfangen.place(x=16, y=152, width=421, height=329) self.scrollbar2 = Scrollbar(self.tEmpfangen, orient=VERTICAL) self.tEmpfangen.config(yscrollcommand=self.scrollbar2.set) self.scrollbar2.pack(side=RIGHT, fill=Y) self.scrollbar2.config(command=self.tEmpfangen.yview) self.tMeldungen = Text(master=self, background="white") self.tMeldungen.place(x=16, y=504, width=657, height=81) self.scrollbar3 = Scrollbar(self.tMeldungen, orient=VERTICAL) self.tMeldungen.config(yscrollcommand=self.scrollbar3.set) self.scrollbar3.pack(side=RIGHT, fill=Y) self.scrollbar3.config(command=self.tMeldungen.yview) # Timer starten self.after(0,self.poll) def poll(self): asyncore.poll(.1) self.after(1, self.poll) # controller import time class Controller(object): def __init__(self): self.model = Model(self.verbunden, self.getrennt, self.ausgeben) self.view = View(self.verbinde, self.sende, self.trenne, self.Halt) self.view.mainloop() def verbinde(self,event): if self.view.bVerbinde.cget( 'state' ) == 'active': self.model.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.model.connect((self.view.eHost.get(),int(self.view.ePort.get()))) self.verbunden() def verbunden(self): self.view.lStatus.config(text="verbunden") self.view.bSende.config(state='active') self.view.bTrenne.config(state='active') self.view.bVerbinde.config(state='disabled') def sende(self,event): if self.view.bSende.cget( 'state' ) == 'active': self.model.buffer = bytes(self.view.tSenden.get("1.0",END),encoding='utf8') def trenne(self,event): if self.view.bTrenne.cget( 'state' ) == 'active': self.view.bSende.config(state='disabled') self.view.bTrenne.config(state='disabled') self.view.bVerbinde.config(state='active') self.view.tMeldungen.insert(INSERT, "Verbindung wurde vom Client um "+time.strftime("%H:%M:%S Uhr",time.localtime())+" getrennt.\n") self.model.handle_close() def getrennt(self): self.view.lStatus.config(text="getrennt") if self.view.bTrenne.cget( 'state' ) == 'active': self.view.tMeldungen.insert(INSERT, "Verbindung wurde vom Server um "+time.strftime("%H:%M:%S Uhr",time.localtime())+" getrennt.\n") self.view.bSende.config(state='disabled') self.view.bTrenne.config(state='disabled') self.view.bVerbinde.config(state='active') def ausgeben(self): self.view.tEmpfangen.insert(INSERT, self.model.Ausgabe) def Halt(self): # Aufräumarbeiten self.model.close() # Schnittstelle schließen self.view.quit() # mainloop beenden self.view.destroy() # Fenster beseitigen # Hauptprogramm c = Controller()