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
| class MulticastSocket(socket.socket):
def __init__(self, port, address=""):
"""
If address is given, the socket acts as sender to this address, otherwise the socket acts as receiver.
In this case, call joinGroup() to tell which address to listen to.
"""
super(MulticastSocket, self).__init__(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
self._port = port
self._address = address
self.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
self.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
except AttributeError:
print "DEBUG::system doesn't support SO_REUSEPORT"
self.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 20)
self.bind(("", port))
def joinGroup(self, address):
""" Listen to the given multicast address
"""
if self._address:
print "WARNING::socket already used as sender (bound to %s)" % self._address
multicast = ord(socket.inet_aton(address)[0]) in range(224, 240)
if not multicast:
raise Exception("address is not a multicast destination (%s)" % repr(address))
self.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
value = struct.pack("=4sl", socket.inet_aton(adress), socket.INADDR_ANY)
self.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, value)
def send(self, data, address=0):
if address:
self._address = address
if self._address:
length = 0
while length < len(data):
l = self.sendto(data, (self._address, self._port))
length += l
else:
raise Exception("destination address not set")
def receive(self):
return self.recvfrom(255) |
Partager