2013-04-29 36 views
5

tại thời điểm tôi làm:Đáng tin cậy được IPV6 Địa chỉ bằng Python

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

này được dựa trên: Finding local IP addresses using Python's stdlib

Tuy nhiên, Điều này có vẻ hơi mơ hồ. Theo như tôi có thể nói, nó sẽ mở một socket đến mysite.com:80, và sau đó trả về địa chỉ đầu tiên cho socket đó, giả sử nó là địa chỉ IPv4. Điều này có vẻ hơi dodgy ... tôi không nghĩ rằng chúng tôi có thể đảm bảo rằng đó là trường hợp.

Đó là câu hỏi đầu tiên của tôi, có an toàn không? Trên máy chủ hỗ trợ IPv6, địa chỉ IPv6 có được trả về bất ngờ không?

Câu hỏi thứ hai của tôi là làm thế nào để tôi nhận địa chỉ IPv6 theo cách tương tự. Im sẽ sửa đổi các chức năng để có một tham số ipv6 tùy chọn.

+0

Đó không phải là một phương pháp đáng tin cậy cho IPv4 . –

+0

Vâng, tôi nghĩ là không. Xin giải thích thêm. –

Trả lời

1

Bạn nên sử dụng chức năng socket.getaddrinfo()

Ví dụ mã để có được 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 
+0

Tôi sẽ tìm thấy nó tốt hơn để lọc cho trường gia đình địa chỉ của kết quả, không phải cho represnetation văn bản của địa chỉ trả về. Xem câu trả lời của tôi. – glglgl

+0

Sẽ lambdas vv ... làm việc trong 2,4? Nó phải tương thích. –

+0

@glglgl Có bạn nói đúng, đó chỉ là một ví dụ nhanh chóng và bẩn thỉu. Vấn đề chủ yếu là chuyển hướng anh ta đến tài liệu socket.getaddrinfo(). – katharas

6

Câu hỏi là, bạn chỉ muốn kết nối, hoặc bạn có thực sự muốn địa chỉ?

Nếu bạn chỉ muốn kết nối, bạn có thể làm

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

và có kết nối được thiết lập.

Tuy nhiên, nếu bạn quan tâm đến địa chỉ, bạn có thể đi một trong các cách sau:

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 

hay, để được gần gũi hơn với 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] 
+0

Vâng, tôi muốn IP, nó đi vào một tập tin cấu hình. –

Các vấn đề liên quan