## Copyright(C) 2008 Litesim Ltd## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; version 2 of the License.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## litesim-specific IPC handling# This one is cross-platform (IronPython or the snake itself (CPython))import sysif sys.platform=='cli': import utils from sockfix import * from utils import * from System import * from socket import *else: old_path = sys.path sys.path.remove('') from socket import * sys.path = old_pathimport Queueimport threadimport randomimport timedef parse_it(it): # parse it, whatever "it" is f = {} cf = 0 i = 0 l = len(it) while i<l: if (it[i]=='\\') and (it[i+1]==':'): i = i + 1 elif (it[i]==':'): cf = cf+1 else: if not f.has_key(cf): f[cf]='' f[cf]=f[cf] + it[i] i = i + 1 retval = [] cf = 0 for cf in f.keys(): retval.append(f[cf]) return retvalclass ipc_handler: def handle_ping(self,addr=None,id=0,params=()): self.call(addr,'PONG',(id,)) def handle_pong(self,addr=None,id=0,params=()): # replace this one print "Got a ping reply from " + addr[0] + ':' + str(addr[1]) def __init__(self,host='0.0.0.0',listener_port='12036'): self.server_sock = socket(AF_INET,SOCK_DGRAM) self.server_sock.bind((host,listener_port)) self.pending_ack = {} self.packet_handlers = { 'PING' : self.handle_ping, 'PONG' : self.handle_pong, } self.worker_threads = [] self.running = False self.PRNG = random.Random(int(time.time())) # It ain't for security purposes, so use the timer fool self.pending_packs = Queue.Queue(0) def call(self,addr,cmd,params,reliable=False): id = self.PRNG.randint(0,999999999) pack = str(id) + ':' + cmd for p in params: pack = pack + ':' + str(p) if reliable: pack = '+' + pack self.pending_ack[id] = pack else: pack = '-' + pack self.server_sock.sendto(pack,addr) def process_pack_loop(self): while self.running: pack = self.pending_packs.put(self.server_sock.recvfrom(65536)) def dispatch_pack_loop(self): while self.running: try: pack = self.pending_packs.get() pack_data = pack[0] pack_addr = pack[1] parsed_pack = parse_it(pack_data) if len(parsed_pack)>1: if (parsed_pack[0] == 'ACK') and self.pending_ack.has_key(parsed_pack[1]): del self.pending_ack[parsed_pack[1]] elif parsed_pack[0].startswith('+') or parsed_pack[0].startswith('-'): if self.packet_handlers.has_key(parsed_pack[1]): params = parsed_pack[2:len(parsed_pack)-2] self.packet_handlers[parsed_pack[1]](addr=pack_addr,id=parsed_pack[0].strip('+').strip('-'),params=params) if pack_data.startswith('+'): server_sock.sendto('ACK:' + parsed_pack[0].strip('+').strip('-')) except Exception, e: print str(e) def start_server(self,thread_count=1): self.running = True for i in range(thread_count): self.worker_threads.append(thread.start_new_thread(self.process_pack_loop,())) self.dispatcher = thread.start_new_thread(self.dispatch_pack_loop,())~