Hallo Michael,
vielleicht zwei Scripte(Client - Server), die wohl nicht punktgenau das treffen, was Du gerne möchtest, aber ein wenig die Phantasie beflügeln und eventuell inspirierend sein können. In Python..., selbstverständlich
Am Ende des zweiten Codes wollte ich noch etwas dazu schreiben..., es taucht nur nicht auf?
Was zum Teufel ist das hier mit diesem Forum? Zitieren kann ich auch nicht, denn unter jedem Zitat taucht
nichts von dem was ich geschrieben habe auf...??
michael, der Code läuft unter Windows einwandfrei!
Du müßtest ihn nur für Linux etwas anpassen.., viel Spaß
Zuerst den Chat Server in Python:
Python
#! /usr/local/bin/python
# -*- coding: utf-8 -*-
##
## chat_sever.py: ein simpler Chat-Server
## Version 0.13, 2002-10-02
## Schule am Ried (www.Schule-am-Ried.de)
## W. Spiegel (walter.spiegel@web.de)
## Magic Key:
## Windows ==> Strg + Untbr/Pause bzw. Ctrl + Break
## Linux ==> Strg + C bzw. Ctrl + C
## To Do:
## - Mitprotokollieren in Datei
## - tkinter-Oberfläche
## - Benutzer rauskicken
## - Einstellungen
##
# stark verändert nach M. Lutz: Programming Python
# ch. 10, S. 547ff (Broadcast + locking hinzugefügt)
# with a little Help from J. Bishop: Java lernen, S. 524ff
#########################################################
# Server side: open a socket on a port, listen for
# a message from a client, and send a broadcast;
# echos lines until 'ENDE' when client closes socket;
# spawns a thread to handle each client connection;
# threads share global memory space with main thread;
#########################################################
import thread, time, string, os
from socket import * # get socket constructor and constants
myHost = '' # server machine, '' means local host
myPort = 8888 # listen on a non-reserved port number
nick_flag = 0 # 0: Adresse, 1: Nick-Name
nicki={} # enthält Adresse und Nick-Name
conn={} # enthält Adresse und connection-Parameter
conn_lock = thread.allocate_lock()
sockobj = socket(AF_INET, SOCK_STREAM) # make a TCP socket object
sockobj.bind((myHost, myPort)) # bind it to server port number
sockobj.listen(5) # allow upto 5 pending connects
if len(myHost) > 0:
print 'Server eingerichtet an Adresse',myHost,'auf Port',str(myPort)
else:
print 'Server eingerichtet auf Port',str(myPort)
if os.name == 'posix':
print 'Magic Key: <Strg> + <C> [<Ctrl> + <C>]'
else:
print 'Magic Key: <Strg> + <Untbr> [<Ctrl> + <Break>]'
#######################
def now():
return time.ctime(time.time()) # current time on the server
#######################
def broadcast(msg, name):
global conn
conn_lock.acquire()
chatter = conn.keys()
for address in chatter:
conn[address].send(name +': '+ msg)
conn_lock.release()
#######################
def handleClient(connection, address): # in spawned thread: reply
global nicki,conn
connection.send('Verbunden! Beenden mit "ENDE", dein Nickname???')
data = connection.recv(1024)
if data: ## doppelte Nicknamen verhindern!
while (data and data in nicki.values() or string.lower(data) in nicki.values() or string.upper(data) in nicki.values()):
connection.send('Nickname "' + data + '" schon vergeben!!!! Denk dir einen neuen Namen aus!!')
data = connection.recv(1024)
if data:
nicki[address]=data
conn_lock.acquire()
conn[address]=connection
conn_lock.release()
broadcast(data + ' im Chatraum! ','*** SERVER ***')
while 1: # read, write a client socket
data = connection.recv(1024)
if not data:
break # keine Daten, das wars!
if nick_flag:
print "Daten von '" + nicki.get(address) + "' erhalten: " + data
else:
print "Daten von " + str(address) + " erhalten: " + data
if data != 'ENDE':
broadcast (data,nicki.get(address) )
else: # data == 'ENDE', beenden!
connection.send('OAIC') # magic string ciao rückwärts!
conn_lock.acquire()
del conn[address]
conn_lock.release()
broadcast('Ciao ' + nicki.get(address) ,'*** SERVER ***')
del nicki[address]
break
print 'Beende Verbindung mit', address
connection.close()
#######################
def dispatcher(): # listen until process killd
while 1: # wait for next connection,
connection, address = sockobj.accept() # pass to thread for service
print 'Server verbunden mit', address,
print ',', now()
thread.start_new(handleClient, (connection,address))
################# Hauptprogramm!
dispatcher()
Display More
...und dann den Chat Klient in Python:
Python
#! /usr/local/bin/python
# -*- coding: utf-8 -*-
##
## chat_client.pyw: simples Chat-Programm
## Version 0.21, 2002-10-02
## siehe auch sar_server.py (Der Chat-Server)
## Dank an David Brand & die G10b
## der Schule am Ried (www.schule-am-ried.de)
## W. Spiegel, walter.spiegel@web.de
## Vers. 0.2: mit Frames, popup-Menü und der chat_list
##
from Tkinter import *
from ScrolledText import *
import tkMessageBox
import tkSimpleDialog
import thread
import time
import os
from socket import *
import chat_list
import string
version = '0.21'
datum = '2002-10-02'
## Adresse und Port setzen (Hier anpassen!)
##address = '192.168.0.35'
address = '127.0.0.1' ## localhost
port = 8888
## globale Variablen
mys = None
thread_flag = 1
verbunden = 0
msg_liste = chat_list.DirList()
sonderzeichen = []
root = Tk()
root.title('Chatten mit Python')
##################################
class einstellungenfenster(tkSimpleDialog.Dialog):
# abgeleitet aus tkSimpleDialog
##Aufruf: einstellungen_ = einstellungenfenster(root)
def body(self, master):
global port, address ## port und addresse sind global!
adr_list = string.split(address,'.') ## TCP/IP-Adresse aufteilen
self.title('Einstellungen')
Label(master, text='Port: ',font="helvetica",anchor=W).grid(row=0)
Label(master, text='TCP/IP:',font="helvetica",anchor=W).grid(row=1)
if os.name == 'posix':
self.e1 = Entry(master,width=19,font="courier")
else: ## windows!
self.e1 = Entry(master,width=18,font="courier")
self.e1.insert('0',port)
self.tcp = Frame(master)
self.e2 = Entry(self.tcp,width=4,font="courier")
self.e3 = Entry(self.tcp,width=4,font="courier")
self.e4 = Entry(self.tcp,width=4,font="courier")
self.e5 = Entry(self.tcp,width=4,font="courier")
self.e2.insert('0',adr_list[0])
self.e3.insert('0',adr_list[1])
self.e4.insert('0',adr_list[2])
self.e5.insert('0',adr_list[3])
self.e1.grid(row=0, column=1)
self.tcp.grid(row=1, column=1)
self.e2.pack(side=LEFT)
self.e3.pack(side=LEFT)
self.e4.pack(side=LEFT)
self.e5.pack(side=LEFT)
return self.e1 # initial focus
def apply(self):
self.a1 = self.e1.get()
self.a2 = self.e2.get()
self.a3 = self.e3.get()
self.a4 = self.e4.get()
self.a5 = self.e5.get()
self.result = 1
##################################
def set_sonderzeichen():
global sonderzeichen
import sys
py_ver = sys.version ## Python-Version testen . . .
python_version = py_ver[0:3]
major = python_version[0]
minor = python_version[2]
if major == '2' and minor == '2': ## benutze unicode
sonderzeichen = [u'ä',u'ö',u'ü',u'Ä',u'Ö',u'Ü',u'ß']
else: ## 'alte' Python-Version
sonderzeichen = ['ä','ö','ü','Ä','Ö','Ü','ß']
def umlauteFilter (zeile):
kodiert = ['ae','oe','ue','Ae','Oe','Ue','ss']
text = ''
for i in range( len(zeile) ):
if zeile[i] in sonderzeichen:
pos = sonderzeichen.index(zeile[i])
text = text + kodiert[pos]
else:
text = text + zeile[i]
return text
def grenzTest(wert, unten,oben):
if (wert >= unten) and (wert <= oben):
return 1 ## true oder wahr
else:
return 0 ## false oder falsch
def nachricht():
global mys, verbunden, thread_flag
## Verbindung aufbauen
mys=socket(AF_INET,SOCK_STREAM)
asciiport = str(port)
textfenster.insert(END, '\n' + 'Verbinde mit ' + address + ', Port: ' + asciiport)
textfenster.see(END)
try:
mys.connect((address,port))
verbunden = 1
except: ## Verbindung misslungen!
textfenster.insert(END, '\n' + 'Keine Verbindung möglich, Server ist abgestürzt!')
textfenster.see(END)
else: ## los gehts!
while 1:
try:
## Hier muss der Empfangen-Befehl hin!
data=mys.recv(1024)
if data == 'OAIC': # Verbindung beenden!
textfenster.insert(END,'\n' + 'Verbindung beendet . . .')
textfenster.see(END)
eingabe.focus_set()
mys.close()
verbunden = 0 # aufräumen . . .
thread_flag = 1
break
else:
textfenster.insert(END,'\n' + data)
textfenster.see(END)
eingabe.focus_set()
time.sleep(0.2)
except:
break ## was schiefgelaufen, das wars . . .
def verbinde():
global thread_flag
## Verbindung zum Server aufbauen und periodisch abfragen
if thread_flag:
thread.start_new_thread(nachricht, ())
thread_flag = 0
def senden():
global mys, verbunden
## Eingabe holen und filtern
msg = umlauteFilter( eingabe.get() )
eingabe.delete('0',END)
## Jetzt Senden!
if verbunden:
msg_liste.addEntry(msg)
mys.send(msg)
else:
tkMessageBox.showinfo("!!!FEHLER!!!","Keine Verbindung zum Server!")
def ende():
global mys, verbunden
if tkMessageBox.askyesno('BeEnDeN?','Wirklich beenden?'):
if verbunden:
msg='ENDE'
mys.send(msg)
mys.close()
root.destroy()
def einstellungen():
global port, address
einstellungen_ = einstellungenfenster(root)
if einstellungen_.result <> None:
z1 = int(einstellungen_.a1)
if grenzTest(z1,512,65536):
port = z1
z2 = int(einstellungen_.a2)
z3 = int(einstellungen_.a3)
z4 = int(einstellungen_.a4)
z5 = int(einstellungen_.a5)
if grenzTest(z2,0,255) and grenzTest(z3,0,255) and grenzTest(z4,0,255) and grenzTest(z5,0,255) :
address = str(z2) + '.' + str(z3) + '.' + str(z4) + '.' + str(z5) ## TCP/IP-Adresse basteln
def info():
tkMessageBox.showinfo('Info',\
"Chat-Programm der G10b\nSchuljahr 2001/2002 \nSchule am Ried \nW. Spiegel\nVersion " + version + ', '+ datum)
def senden_(event):
senden()
def ende_(event):
ende()
def verbinde_(event):
verbinde()
def popup_(event):
popup.post(event.x_root, event.y_root)
############################
## MAIN - Hauptprogramm
############################
set_sonderzeichen() ## Sonderzeichen-Liste setzen
fpopup = Frame(root,width=500)
fpopup.pack(expand=1, fill=BOTH)
popup = Menu(fpopup,tearoff=0)
popup.add_command(label='Einstellungen', command=einstellungen)
popup.add_separator()
popup.add_command(label='Info', command=info)
popup.add_separator()
popup.add_command(label='Beenden', command=ende)
textfenster = ScrolledText(fpopup,width=90,height=24,background='white')
textfenster.pack(fill=BOTH,expand=YES)
eingabe = Entry(fpopup,width=60,background='white')
eingabe.pack(side=LEFT,fill=BOTH,expand=YES)
##
## Bindings . . .
eingabe.bind('<Return>',senden_)
eingabe.bind('<F1>',senden_)
eingabe.bind('<Control-y>',verbinde_)
eingabe.bind('<Control-Y>',verbinde_)
##eingabe.bind('<Alt-F4>',ende_)
##textfenster.bind('<Alt-F4>',ende_)
textfenster.bind('<Control-y>',verbinde_)
textfenster.bind('<Control-Y>',verbinde_)
textfenster.bind('<Button-3>',popup_)
## Buttons
but2 = Button(fpopup,text='Senden', command = senden)
but2.pack(side = LEFT,expand=NO)
but1 = Button(fpopup,text='Verbinden', command = verbinde)
but1.pack(side = LEFT,expand=NO)
but4 = Button(fpopup,text='Info', command = info)
but4.pack(side = LEFT,expand=NO)
but3 = Button(fpopup,text='Beenden', command = ende)
but3.pack(side = LEFT,expand=NO)
## los geht's
root.mainloop()
Display More