from socket import socket, AF_INET,SOCK_DGRAM,IPPROTO_UDP,SOL_SOCKET,SO_REUSEADDR,IP_MULTICAST_TTL,IP_MULTICAST_LOOP,INADDR_ANY,inet_aton,IP_ADD_MEMBERSHIP,IPPROTO_IP import struct import threading import logging log = None from select import select GROUP = '224.110.42.23' PORT = 42023 log = logging.getLogger('CholerabNet') class CholerabMulicastNet(threading.Thread): def __init__(self,cholerab,group=GROUP,port=PORT): threading.Thread.__init__(self) self.cholerab=cholerab self.group=group self.port=port self.initSocket() def send_char(self,x,y,char): """ translates given params into network message """ self.send_mc("%s %d %d" %(str(ord(char)),x,y)) def send_mc(self,arg): """ Sends message via multicast""" try: log.debug("Sending '%s' to %s:%d" % (arg,self.group,self.port)) self.ignore_next += 1# we need this to work together correctly with reused sockets self.s.sendto("%s" % arg,0,(self.group,self.port)) except Exception ,e: self.ignore_next -=1 log.error("IN send_mc:%s"%str(e)) def initSocket (self,rcv=1): ''' Initializes a Multicast socket ''' host = '' log.debug("Setting up Multicast Socket") self.s = socket(AF_INET,SOCK_DGRAM, IPPROTO_UDP) self.s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) self.s.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, 32) self.s.setsockopt(IPPROTO_IP,IP_MULTICAST_LOOP,1) # we do not want our own packets to be replayed if rcv==1: log.debug("Configuring for Read AND Write") self.s.bind((host,PORT)) mreq = struct.pack("4sl", inet_aton(GROUP), INADDR_ANY) self.s.setsockopt(IPPROTO_IP,IP_ADD_MEMBERSHIP,mreq) def run(self): self.running = 1 self.ignore_next = 0 while self.running: # break if we do not want to loop on ready,output,exception = select([self.s],[],[],1) # try every second for r in ready: if r == self.s: log.debug(str(self.ignore_next)) (data,addr) = self.s.recvfrom(1024) if not self.ignore_next: log.debug("Received Data from %s, data %s"%(str(addr),str(data))) self.receive_net(addr,data) else: self.ignore_next -= 1 def send_stupid(self,addr): """ sends YOU ARE MADE OF STUPID to the right host """ #TODO implement me pass def receive_net(self,addr,data): """ resolves which nick sent the message TODO handle user resolution in mulicast """ try: address,port = addr arr = str(data).split() char = arr[0] x = arr[1] y = arr[2] self.cholerab.write_char(int(x),int(y),chr(int(char))) except Exception, e: log.error("Triggered YOU ARE MADE OF STUPID: %s" % str(e)) self.send_stupid(addr) def stop(self): ''' stops the whole treading stuff gracefully ''' self.running=0