我们从Python开源项目中,提取了以下15个代码示例,用于说明如何使用socket.IP_MULTICAST_LOOP。
def setup_ipv4_multicast_socket(ifaddrs, if_name, addr): #todo: if_name ignored s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(("", Config.udp_multicast.port)) s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, Config.udp_multicast.ttl) s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0) mreq = struct.pack("4sl", socket.inet_aton(addr), socket.INADDR_ANY) s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) s.setblocking(0) multicast_socket_ipv4.append((s,addr)) return True
def getLoopbackMode(self): return self.socket.getsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP)
def setLoopbackMode(self, mode): mode = struct.pack("b", operator.truth(mode)) self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, mode)
def receiver(service='mihome'): from plugins import gateway assert service in MULTICAST, 'No such service' store = get_store() address, port = MULTICAST.get(service) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(("0.0.0.0", port)) mreq = struct.pack("=4sl", socket.inet_aton(address), socket.INADDR_ANY) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, SOCKET_BUFSIZE) sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) current = {} while True: data, _ = sock.recvfrom(SOCKET_BUFSIZE) # buffer size is 1024 bytes print(datetime.now().isoformat(), data) if service == 'mihome': message = json.loads(data.decode()) data = json.loads(message['data']) if message.get('model') in ('sensor_ht', 'weather.v1') and not sensor_ht.process(conn, cursor, current, message, data): continue elif message.get('model') == 'magnet': magnet.process(store, message, data) elif message.get('model') == 'gateway': gateway.process(store, message, data) current = {} elif service == 'yeelight': yeelight.process(data.decode())
def create_multicast_sock(own_ip, remote_addr, bind_to_multicast_addr): """Create UDP multicast socket.""" sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setblocking(False) sock.setsockopt( socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(own_ip)) sock.setsockopt( socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(remote_addr[0]) + socket.inet_aton(own_ip)) sock.setsockopt( socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) sock.setsockopt( socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(own_ip)) # I have no idea why we have to use different bind calls here # - bind() with multicast addr does not work with gateway search requests # on some machines. It only works if called with own ip. # - bind() with own_ip does not work with ROUTING_INDICATIONS on Gira # knx router - for an unknown reason. if bind_to_multicast_addr: sock.bind((remote_addr[0], remote_addr[1])) else: sock.bind((own_ip, 0)) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0) return sock
def new_socket(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # SO_REUSEADDR should be equivalent to SO_REUSEPORT for # multicast UDP sockets (p 731, "TCP/IP Illustrated, # Volume 2"), but some BSD-derived systems require # SO_REUSEPORT to be specified explicity. Also, not all # versions of Python have SO_REUSEPORT available. # Catch OSError and socket.error for kernel versions <3.9 because lacking # SO_REUSEPORT support. try: reuseport = socket.SO_REUSEPORT except AttributeError: pass else: try: s.setsockopt(socket.SOL_SOCKET, reuseport, 1) except (OSError, socket.error) as err: # OSError on python 3, socket.error on python 2 if not err.errno == errno.ENOPROTOOPT: raise # OpenBSD needs the ttl and loop values for the IP_MULTICAST_TTL and # IP_MULTICAST_LOOP socket options as an unsigned char. ttl = struct.pack(b'B', 255) s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl) loop = struct.pack(b'B', 1) s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, loop) s.bind(('', _MDNS_PORT)) return s
def get_multicast_socket(sock=None): if not sock: sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(0.001) # set multicast interface to any local interface sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton('0.0.0.0')) # Enable multicast, TTL should be <32 (local network) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 5) # Allow reuse of addresses sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Allow receiving multicast broadcasts (subscribe to multicast group) try: mreq = struct.pack('4sL', socket.inet_aton(multicast_ip), socket.INADDR_ANY) sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) # Do not loop back own messages sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 0) except OSError as e: logger.error('Unable to obtain socket with multicast enabled.') raise e port = None for i in range(30100, 30105): try: # Binding to 0.0.0.0 results in multiple messages if there is multiple interfaces available # Kept as-is to avoid losing messages sock.bind(('0.0.0.0', i)) port = i break except OSError as e: # Socket already in use without SO_REUSEADDR enabled continue if not port: raise RuntimeError('No IMC multicast ports free on local interface.') return sock
def __init__(self, bindaddress=None): """Creates an instance of the Zeroconf class, establishing multicast communications, listening and reaping threads.""" globals()['_GLOBAL_DONE'] = 0 self.intf = bindaddress self.group = ('', _MDNS_PORT) self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) except Exception: # SO_REUSEADDR should be equivalent to SO_REUSEPORT for # multicast UDP sockets (p 731, "TCP/IP Illustrated, # Volume 2"), but some BSD-derived systems require # SO_REUSEPORT to be specified explicity. Also, not all # versions of Python have SO_REUSEPORT available. So # if you're on a BSD-based system, and haven't upgraded # to Python 2.3 yet, you may find this library doesn't # work as expected. # pass self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 255) self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1) try: self.socket.bind(self.group) except Exception: # Some versions of linux raise an exception even though # the SO_REUSE* options have been set, so ignore it # pass if self.intf is not None: self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(self.intf) + socket.inet_aton('0.0.0.0')) self.socket.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0')) self.listeners = [] self.browsers = [] self.services = {} self.cache = DNSCache() self.condition = threading.Condition() self.engine = Engine(self) self.listener = Listener(self) self.reaper = Reaper(self)
def __init__(self, port, callback_obj, ttl=1, enable_loopback=False, bind_addr=''): asyncore.dispatcher.__init__(self) # self.lock = threading.RLock() self.MAX_MTU = 1500 self.callback_obj = None self.port = port self.multicastSet = Set([]) self.lock = threading.RLock() self.ttl = ttl self.enable_loopback = enable_loopback if callback_obj is not None and isinstance(callback_obj, IUdpCallback): self.callback_obj = callback_obj else: raise Exception('callback_obj is None or not an instance of IUdpCallback class') try: self.create_socket(socket.AF_INET, socket.SOCK_DGRAM) self.set_reuse_addr() try: socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) except AttributeError: pass # Some systems don't support SO_REUSEPORT # for both SENDER and RECEIVER to restrict the region self.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, self.ttl) # for SENDER to choose whether to use loop back if self.enable_loopback: self.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1) else: self.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0) self.bind_addr = bind_addr if self.bind_addr is None or self.bind_addr == '': self.bind_addr = socket.gethostbyname(socket.gethostname()) # for both SENDER and RECEIVER to bind to specific network adapter self.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(self.bind_addr)) # for RECEIVE to receive from multiple multicast groups self.bind(('', port)) except Exception as e: print e traceback.print_exc() self.sendQueue = Queue.Queue() # thread-safe queue AsyncController.instance().add(self) if self.callback_obj is not None: self.callback_obj.on_started(self) # Even though UDP is connectionless this is called when it binds to a port