00001
00002
00003 import socket
00004 import struct
00005 import fcntl
00006 import array
00007
00008 import network
00009
00010 class InterfaceNotFound(Exception):
00011 def __init__(self, ifname):
00012 Exception.__init__(self, ifname)
00013
00014 class Datagram:
00015 """A datagram socket wrapper.
00016 """
00017 iflist = None
00018
00019 def __init__(self, address, port):
00020
00021 if address is not None and len(address) > 0:
00022 try:
00023 socket.inet_aton ( address )
00024 except socket.error:
00025 try:
00026 ifconfig = network.ifconfig()
00027 except network.IfConfigNotSupported:
00028 raise InterfaceNotFound(address)
00029
00030 if address in ifconfig:
00031 iff = ifconfig[address]
00032 else:
00033 raise InterfaceNotFound (address)
00034 self.local_address = iff.ip
00035 else:
00036 self.local_address = address
00037 else:
00038 self.local_address = None
00039
00040 if self.local_address is None: self.local_address = ''
00041
00042 self._socket = socket.socket (socket.AF_INET, socket.SOCK_DGRAM)
00043 self._socket.setsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
00044
00045 self.address = address
00046 self.port = port
00047 self.multicast = False
00048
00049 self.bind()
00050
00051 def bind(self):
00052 self._socket.bind ( (self.local_address, self.port) )
00053
00054 def pipe(self, ostream):
00055 while True:
00056 self.pipeone (ostream)
00057
00058 def pipeone(self, ostream, size=1500):
00059 data, addr = self._socket.recvfrom(size)
00060
00061 if ostream is not None:
00062 if callable(ostream): target = ostream
00063 else: target = ostream.write
00064 return target (data)
00065 else:
00066 return data
00067
00068 def read(self, size=1500):
00069 return self.pipeone (None, size)
00070 recv = read
00071
00072 def cleanup(self):
00073 pass
00074
00075 def close(self):
00076 self.cleanup()
00077 self._socket.close()
00078
00079 def __unicast__(self):
00080 return "DatagramReceiver [{0}] {1}:{2}".format (self._socket, self.local_address, self.port)
00081
00082 class Multicast(Datagram):
00083 def __init__(self, bind_address_or_interface, multicast_address, port, ttl=32, loop=1):
00084 Datagram.__init__ (self, bind_address_or_interface, port )
00085
00086 self.ttl = ttl
00087 self.loop = loop
00088 self.multicast_address = multicast_address
00089 self.multicast = True
00090
00091 self._socket.setsockopt (socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, self.ttl)
00092 self._socket.setsockopt (socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, self.loop)
00093
00094 self._socket.setsockopt (socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(self.local_address))
00095 self._socket.setsockopt (socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton (self.multicast_address) + socket.inet_aton(self.local_address))
00096
00097 def bind(self):
00098 self._socket.bind ( ('', self.port) )
00099
00100 def cleanup(self):
00101 self._socket.setsockopt (socket.SOL_IP, socket.IP_DROP_MEMBERSHIP, socket.inet_aton (self.multicast_address) + socket.inet_aton(self.local_address))
00102
00103 def __unicast__(self):
00104 return "MulticastReceiver [{0}] {1}:{2} @ {3}".format (self._socket, self.multicast_address, self.port, self.local_address)
00105
00106
00107 def DatagramReceiver (destination_address, destination_port, source_interface=None, ttl=32):
00108 multicast = ord(socket.inet_aton(destination_address)[0]) in range(224, 240)
00109
00110 if multicast:
00111 receiver = Multicast (source_interface, destination_address, destination_port, ttl=ttl)
00112 else:
00113 receiver = Datagram (destination_address, destination_port)
00114
00115 return receiver
00116
00117
00118