简体   繁体   中英

Reliably get IPV6 Address in Python

at the moment I do:

def get_inet_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(('mysite.com', 80))
    return s.getsockname()[0]

This was based on: Finding local IP addresses using Python's stdlib

However, This looks a bit dubious. As far as I can tell, it opens a socket to mysite.com:80, and then returns the first address for that socket, assuming it to be an IPv4 address. This seems a bit dodgy... i dont think we can ever guaranteee that to be the case.

Thats my first question, is it safe? On an IPv6-enable server, could the IPv6 address ever be returned unexpectedly?

My second question, is how do I get the IPv6 address in a similar way. Im going to modify the function to take an optional ipv6 paramater.

The question is, do you just want to connect, or do you really want the address?

If you just want to connect, you can do

s = socket.create_connection(('mysite.com', 80))

and have the connection established.

However, if you are interested in the address, you can go one of these ways:

def get_ip_6(host, port=0):
    import socket
    # search only for the wanted v6 addresses
    result = socket.getaddrinfo(host, port, socket.AF_INET6)
    return result # or:
    return result[0][4][0] # just returns the first answer and only the address

or, to be closer to another, already presented solution :

def get_ip_6(host, port=0):
     # search for all addresses, but take only the v6 ones
     alladdr = socket.getaddrinfo(host,port)
     ip6 = filter(
         lambda x: x[0] == socket.AF_INET6, # means its ip6
         alladdr
     )
     # if you want just the sockaddr
     # return map(lambda x:x[4],ip6)
     return list(ip6)[0][4][0]

You should be using the function socket.getaddrinfo()

Example code to get IPv6

def get_ip_6(host,port=80):
    # discard the (family, socktype, proto, canonname) part of the tuple
    # and make sure the ips are unique
    alladdr = list(
        set(
            map(
                lambda x: x[4],
                socket.getaddrinfo(host,port)
            )
        )
    )
    ip6 = filter(
        lambda x: ':' in x[0], # means its ip6
        alladdr
    )
    return ip6

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM