我们从Python开源项目中,提取了以下16个代码示例,用于说明如何使用socket.IP_MULTICAST_IF。
def getOutgoingInterface(self): i = self.socket.getsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF) return socket.inet_ntoa(struct.pack("@i", i))
def _setInterface(self, addr): i = socket.inet_aton(addr) self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, i) return 1
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 subscribe_multicast(interface): """subscribe to the mcast addr""" sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(interface.ipv4_address)) mreq = socket.inet_aton(interface.mcastaddr) + socket.inet_aton(interface.ipv4_address) sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) sock.bind(('', 52122)) return sock
def set_ipv4_multicast_source_address(sock, source_address): """Sets the given socket up to send multicast from the specified source. Ensures the multicast TTL is set to 1, so that packets are not forwarded beyond the local link. :param sock: An opened IP socket. :param source_address: A string representing an IPv4 source address. """ sock.setsockopt( socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 1) sock.setsockopt( socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(source_address))
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
def __init__( self, interfaces=InterfaceChoice.All, ): """Creates an instance of the Zeroconf class, establishing multicast communications, listening and reaping threads. :type interfaces: :class:`InterfaceChoice` or sequence of ip addresses """ # hook for threads self._GLOBAL_DONE = False self._listen_socket = new_socket() interfaces = normalize_interface_choice(interfaces, socket.AF_INET) self._respond_sockets = [] for i in interfaces: log.debug('Adding %r to multicast group', i) try: self._listen_socket.setsockopt( socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(_MDNS_ADDR) + socket.inet_aton(i)) except socket.error as e: if get_errno(e) == errno.EADDRINUSE: log.info( 'Address in use when adding %s to multicast group, ' 'it is expected to happen on some systems', i, ) elif get_errno(e) == errno.EADDRNOTAVAIL: log.info( 'Address not available when adding %s to multicast ' 'group, it is expected to happen on some systems', i, ) continue else: raise respond_socket = new_socket() respond_socket.setsockopt( socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(i)) self._respond_sockets.append(respond_socket) self.listeners = [] self.browsers = {} self.services = {} self.servicetypes = {} self.cache = DNSCache() self.condition = threading.Condition() self.engine = Engine(self) self.listener = Listener(self) self.engine.add_reader(self.listener, self._listen_socket) self.reaper = Reaper(self) self.debug = None
def run(self): """Run the server.""" # Listen for UDP port 1900 packets sent to SSDP multicast address ssdp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ssdp_socket.setblocking(False) # Required for receiving multicast ssdp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) ssdp_socket.setsockopt( socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(self.host_ip_addr)) ssdp_socket.setsockopt( socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton("239.255.255.250") + socket.inet_aton(self.host_ip_addr)) ssdp_socket.bind(("239.255.255.250", 1900)) while True: if self._interrupted: clean_socket_close(ssdp_socket) return try: read, _, _ = select.select( [self._interrupted_read_pipe, ssdp_socket], [], [ssdp_socket]) if self._interrupted_read_pipe in read: # Implies self._interrupted is True clean_socket_close(ssdp_socket) return elif ssdp_socket in read: data, addr = ssdp_socket.recvfrom(1024) else: continue except socket.error as ex: if self._interrupted: clean_socket_close(ssdp_socket) return _LOGGER.error("UPNP Responder socket exception occured: %s", ex.__str__) if "M-SEARCH" in data.decode('utf-8'): # SSDP M-SEARCH method received, respond to it with our info resp_socket = socket.socket( socket.AF_INET, socket.SOCK_DGRAM) resp_socket.sendto(self.upnp_response, addr) resp_socket.close()