modelnine hat geschrieben:
Aber: ohne dass Du irgendwelchen Code den Du zu gebrauchen denkst postest ist es unheimlich schwierig was dazu zu sagen.
--- Heiko.
Also ich bastle einem Mess-Server der den Zugriff von verschieden Threats auf die Messgeräte regelt. Da Ganze ist auch ein I-learn-python (und programmiern) projekt.
Der Source-Code des Servers ist:
Code: Alles auswählen
import pickle
import Queue
import socket
import threading
import code
import test
from sendclass import *
## def martin(was):
## print "martin is " + was;
## def gina(was, wasnoch):
## print "gina is " + was + " und "+ wasnoch;
class Command:
def __init__( self, func, *args):
self.func=func;
self.args=args;
def __call__(self):
apply(self.func, self.args);
# A revised version of our thread class:
class ServerThread ( threading.Thread ):
# Note that we do not override Thread's __init__ method.
# The Queue module makes this not necessary.
def run(self):
# Have our thread serve "forever":
while True:
# Get a client out of the queue
client = clientPool.get()
# Check if we actually have an actual client in the client variable:
if client != None:
print 'Received connection:', client[1][0]
client[0].send('1');
command=client[0].recv(1024)
if command[0:5].upper()=='SETUP':
file_handler=file('test.py','r')
class_all=install_class(file_handler, 'test')
client[0].send(repr(len(class_all)+1));
if client[0].recv(1024)=='1':
print "Settin up a client ."
for i in class_all:
client[0].send(i)
if client[0].recv(1024)=='1':
print "."
client[0].send('print \'Installed Object: test \'');
if client[0].recv(1024)=='1':
print ". the client is setup"
else:
while True:
if command[0:4].upper()=='CODE':
if command.__len__()>4 :
src_code=command[4:]
else:
src_code=client[0].recv(1024);
exec code.compile_command(src_code) in globals();
client[0].send("1");
elif command[0:6].upper()=='PICKLE':
if command.__len__()>6:
func_def=command[6:]
else:
func_def=client[0].recv(1024);
function=pickle.loads(func_def);
client[0].send(pickle.dumps(function.__call__()));
elif command[0:4].upper() == 'QUIT':
client[0].close()
print 'Closed connection:', client[1][0];
break;
else:
print 'Error: ' + command + ' is no Command';
command=client[0].recv(1024)
# Create our Queue:
clientPool = Queue.Queue(0)
test=test.test()
# Start two threads:
for x in xrange(10):
ServerThread().start()
# Set up the server:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('', 2727))
server.listen(5)
# Have the server serve "forever":
while True:
clientPool.put(server.accept())
Das module sendclass ist
Code: Alles auswählen
def install_class_from_string(string, name):
index=0
lines=string.splitlines()
num=lines.__len__()
res=''
while index<num:
if lines[index].strip().startswith('def'):
func=lines[index] + '\n';
index=index+1
while index<num:
if lines[index].strip().startswith('def'):
break;
func=func + lines[index] + '\n';
index=index+1
## print 'Start func: \n' + func + 'End func\n'
res=res+rewrite_func(func, name);
else:
res=res+lines[index] + '\n';
index=index+1;
## res=res + 'print \'Installed Object: ' + name +'\'';
return res
def rewrite_func(string, name):
def getDefName(string):
string=string.strip()
return string[4:string.find('(')].strip()
def getDefArg(string):
argstr=string[string.find('(')+1:string.find(')')];
num=argstr.count(',')+1;
args=argstr.split(',');
allargs='';
for i in range(0,num):
if not(args[i].find('=')==-1):
args[i]=args[i][0:args[i].find('=')];
if not(args[i].strip()=='self'):
allargs=allargs + ', ' + args[i].strip();
return allargs
res=''
lastisdef=False;
iscommend=False;
func_name=''
args=''
for i in string.splitlines():
if i.strip().startswith('def') :
res= res + i + '\n';
lastisdef=True;
func_name=getDefName(i);
args=getDefArg(i)
elif lastisdef and i.strip().startswith('"""'):
if i.count('"""') < 2:
iscommend=True;
lastisdef=False;
res= res + i + '\n';
elif iscommend:
lastisdef=False;
res= res + i + '\n';
if i.find('"""'):
iscommend=False;
else:
lastisdef=False;
if func_name=='__init__':
return string
res=res + '\tclient.send(\'Pickle\')\n';
res=res + '\ta=Command(' + name + '.' + func_name + args + ') \n';
res=res + '\tclient.send(pickle.dumps(a)) \n';
res=res + '\tret=client.recv(1024) \n';
res=res + '\treturn pickle.loads(ret) \n';
return res
def getclassdefinition(file, name):
class_all=[]
class_str=''
index=0
def getclassname(string):
if not(string.find('(')==-1):
return string[6:string.find('(')].strip()
else:
return string[6:string.find(':')].strip()
lines=file.readlines();
num=lines.__len__()
while index<num:
if lines[index].startswith('class'):
if getclassname(lines[index])==name:
class_str=class_str+lines[index]
index=index+1
while index<num:
if not(lines[index].startswith(' ') or lines[index]=='\n'):
break
class_str=class_str+lines[index];
index=index+1
class_all.append(class_str)
else:
index=index+1
while index<num:
if not(lines[index].startswith(' ') or lines[index]=='\n'):
break
index=index+1
else:
class_all.append(lines[index]);
index=index+1;
return class_all
def install_class(myfile, name):
class_def=getclassdefinition(myfile, name);
num=len(class_def)-1
class_def[num]=install_class_from_string(class_def[num], name)
return class_def
test.py ist
Code: Alles auswählen
from time import sleep
class test1:
pass
class test:
""" Class description
slkdfj
"""
voltage=3.3
def __init__(self, voltage=3.3):
self.voltage=voltage
def getVoltage(self):
""" Function description
sdfsdfsd """
print 'Got the voltage'
return self.voltage
def setVolatge(self, voltage=3.3):
""" single """
print 'Set the voltage'
self.voltage=voltage
def sleep(time=30):
sleep(time)
und der client ist :
Code: Alles auswählen
import pickle
import socket
import threading
import code
class Command:
def __init__( self, func, *args):
self.func=func;
self.args=args;
def __call__(self):
apply(self.func, self.args);
def install_function(self, string):
def getname(string):
string=string.strip()
return string[4:string.find('(')].strip()
def getarg(string):
argstr=string[string.find('(')+1:string.find(')')];
num=argstr.count(',')+1;
args=argstr.split(',');
allargs='';
for i in range(0,num):
args[i]=args[i][0:args[i].find('=')];
allargs=allargs + ', ' + args[i].strip();
return allargs
res=''
lastisdef=False;
iscommend=False;
func_name=''
args=''
for i in string.splitlines():
if i.startswith('def') :
res= res + i + '\n';
lastisdef=True;
func_name=getname(i);
args=getarg(i)
elif lastisdef and i.find('"""'):
if i.count('"""') < 2:
iscommend=True;
lastisdef=False;
res= res + i + '\n';
elif iscommend:
lastisdef=False;
res= res + i + '\n';
if i.find('"""'):
iscommend=False;
else:
lastisdef=False;
res=res + '\tclient.send(\'Pickle\')\n';
res=res + '\ta=Command(' + func_name + args + ') \n';
res=res + '\tclient.send(pickle.dumps(a)) \n';
res=res + '\tret=client.recv(1024) \n';
res=res + '\treturn pickle.loads(ret) \n';
exec code.compile_command(res) in globals();
client.send('Code');
client.send(string);
if client.recv(1024)=='1':
print "Installed Function " + func_name + " successfully!"
def setup():
exec 'client=socket.socket(socket.AF_INET, socket.SOCK_STREAM)' in globals()
client.connect(('localhost', 2727));
ack=client.recv(10)
if ack[0:1]=='1' :
print 'Connection succesfull!'
client.send('SETUP')
num=int(client.recv(1024))
print num
for i in range(num):
client.send("1")
src=client.recv(1024)
print 'begin of source \n' + src +'end of source \n'
exec code.compile_command(src) in globals()
client.send("1");
Das Ziel ist, dass ich auf der Client-Seite einige GUI habe und aber auch in eine shell messbefehle eintippen kann. Ich möchte deshalb deshalb alle objekte für die Messgräte (die sind nur einige; ich werde also per exec nicht beliebig viele objekte erzeugen) auf der obersten Ebene instanzieren, dass Messroutinen auf allen Ebene können laufen. Der User sollte von der Kommunikation des Client/Server (auch text-basiert) nichts wissen muessen! Und seine Scripte sowohl local als auch auf dem Server ohne änderung laufen lassen können.
Sicherheitspolitische bedenken gegen meine Server habe ich mal ausser acht gelassen. Er wird in einer geschlossen umgebung laufen.
Gruss
Bossi