Finding local IP addresses using Python's stdlib

后端 未结 30 2606
北恋
北恋 2020-11-21 23:54

How can I find local IP addresses (i.e. 192.168.x.x or 10.0.x.x) in Python platform independently and using only the standard library?

相关标签:
30条回答
  • 2020-11-22 00:19

    On Debian (tested) and I suspect most Linux's..

    import commands
    
    RetMyIP = commands.getoutput("hostname -I")
    

    On MS Windows (tested)

    import socket
    
    socket.gethostbyname(socket.gethostname())
    
    0 讨论(0)
  • 2020-11-22 00:20
    import socket
    socket.gethostbyname(socket.gethostname())
    

    This won't work always (returns 127.0.0.1 on machines having the hostname in /etc/hosts as 127.0.0.1), a paliative would be what gimel shows, use socket.getfqdn() instead. Of course your machine needs a resolvable hostname.

    0 讨论(0)
  • 2020-11-22 00:20

    This answer is my personal attempt to solve the problem of getting the LAN IP, since socket.gethostbyname(socket.gethostname()) also returned 127.0.0.1. This method does not require Internet just a LAN connection. Code is for Python 3.x but could easily be converted for 2.x. Using UDP Broadcast:

    import select
    import socket
    import threading
    from queue import Queue, Empty
    
    def get_local_ip():
            def udp_listening_server():
                s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                s.bind(('<broadcast>', 8888))
                s.setblocking(0)
                while True:
                    result = select.select([s],[],[])
                    msg, address = result[0][0].recvfrom(1024)
                    msg = str(msg, 'UTF-8')
                    if msg == 'What is my LAN IP address?':
                        break
                queue.put(address)
    
            queue = Queue()
            thread = threading.Thread(target=udp_listening_server)
            thread.queue = queue
            thread.start()
            s2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s2.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
            waiting = True
            while waiting:
                s2.sendto(bytes('What is my LAN IP address?', 'UTF-8'), ('<broadcast>', 8888))
                try:
                    address = queue.get(False)
                except Empty:
                    pass
                else:
                    waiting = False
            return address[0]
    
    if __name__ == '__main__':
        print(get_local_ip())
    
    0 讨论(0)
  • 2020-11-22 00:21

    Variation on ninjagecko's answer. This should work on any LAN that allows UDP broadcast and doesn't require access to an address on the LAN or internet.

    import socket
    def getNetworkIp():
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        s.connect(('<broadcast>', 0))
        return s.getsockname()[0]
    
    print (getNetworkIp())
    
    0 讨论(0)
  • 2020-11-22 00:22

    If you don't want to use external packages and don't want to rely on outside Internet servers, this might help. It's a code sample that I found on Google Code Search and modified to return required information:

    def getIPAddresses():
        from ctypes import Structure, windll, sizeof
        from ctypes import POINTER, byref
        from ctypes import c_ulong, c_uint, c_ubyte, c_char
        MAX_ADAPTER_DESCRIPTION_LENGTH = 128
        MAX_ADAPTER_NAME_LENGTH = 256
        MAX_ADAPTER_ADDRESS_LENGTH = 8
        class IP_ADDR_STRING(Structure):
            pass
        LP_IP_ADDR_STRING = POINTER(IP_ADDR_STRING)
        IP_ADDR_STRING._fields_ = [
            ("next", LP_IP_ADDR_STRING),
            ("ipAddress", c_char * 16),
            ("ipMask", c_char * 16),
            ("context", c_ulong)]
        class IP_ADAPTER_INFO (Structure):
            pass
        LP_IP_ADAPTER_INFO = POINTER(IP_ADAPTER_INFO)
        IP_ADAPTER_INFO._fields_ = [
            ("next", LP_IP_ADAPTER_INFO),
            ("comboIndex", c_ulong),
            ("adapterName", c_char * (MAX_ADAPTER_NAME_LENGTH + 4)),
            ("description", c_char * (MAX_ADAPTER_DESCRIPTION_LENGTH + 4)),
            ("addressLength", c_uint),
            ("address", c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
            ("index", c_ulong),
            ("type", c_uint),
            ("dhcpEnabled", c_uint),
            ("currentIpAddress", LP_IP_ADDR_STRING),
            ("ipAddressList", IP_ADDR_STRING),
            ("gatewayList", IP_ADDR_STRING),
            ("dhcpServer", IP_ADDR_STRING),
            ("haveWins", c_uint),
            ("primaryWinsServer", IP_ADDR_STRING),
            ("secondaryWinsServer", IP_ADDR_STRING),
            ("leaseObtained", c_ulong),
            ("leaseExpires", c_ulong)]
        GetAdaptersInfo = windll.iphlpapi.GetAdaptersInfo
        GetAdaptersInfo.restype = c_ulong
        GetAdaptersInfo.argtypes = [LP_IP_ADAPTER_INFO, POINTER(c_ulong)]
        adapterList = (IP_ADAPTER_INFO * 10)()
        buflen = c_ulong(sizeof(adapterList))
        rc = GetAdaptersInfo(byref(adapterList[0]), byref(buflen))
        if rc == 0:
            for a in adapterList:
                adNode = a.ipAddressList
                while True:
                    ipAddr = adNode.ipAddress
                    if ipAddr:
                        yield ipAddr
                    adNode = adNode.next
                    if not adNode:
                        break
    

    Usage:

    >>> for addr in getIPAddresses():
    >>>    print addr
    192.168.0.100
    10.5.9.207
    

    As it relies on windll, this will work only on Windows.

    0 讨论(0)
  • 2020-11-22 00:23

    I'm afraid there aren't any good platform independent ways to do this other than connecting to another computer and having it send you your IP address. For example: findmyipaddress. Note that this won't work if you need an IP address that's behind NAT unless the computer you're connecting to is behind NAT as well.

    Here's one solution that works in Linux: get the IP address associated with a network interface.

    0 讨论(0)
提交回复
热议问题