1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
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
|