All pastes #959577 Raw Edit

Untitled

public text v1 · immutable
#959577 ·published 2008-03-27 15:22 UTC
rendered paste body
#
# 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 sys

if 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_path

import Queue
import thread
import random
import time

def 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 retval

class 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,())
~