2012-06-13 7 views
6

Ho utilizzato in precedenza il seguente codice per associare l'indirizzo IPv4 al socket Python come indirizzo IP di origine.Associare l'indirizzo IPv6 al socket Python come indirizzo IP di origine

import socket 
true_socket = socket.socket 
def bound_socket(*a, **k): 
    sock = true_socket(*a, **k) 
    sock.bind((sourceIP, 0)) 
    return sock 
socket.socket = bound_socket 

Il codice sopra riportato funziona per l'indirizzo IPv6? In caso contrario, come posso associare un indirizzo IPv6?

Grazie in anticipo!

risposta

6

si può provare questo, per ottenere un indirizzo IPv6, è consigliabile utilizzare socket.getaddrinfo restituirà tutti i diversi indirizzi IPv4 e IPv6, è possibile associare tutti o solo che mai quello che si desidera/bisogno.

import socket 
def bound_socket(*a, **k): 
    sock = socket.socket(*a, **k) 
    if socket.AF_INET6 in a: 
     if not socket.has_ipv6: 
      raise ValueError("There's no support for IPV6!") 
     else: 
      address = [addr for addr in socket.getaddrinfo(source_ip, None) 
         if socket.AF_INET6 == addr[0]] # You ussually want the first one. 
      if not address: 
       raise ValueError("Couldn't find ipv6 address for source %s" % source_ip) 
      sock.bind(address[0][-1]) 
    else: 
     sock.bind((source_ip, 0)) 
    return sock 
2

Questo dovrebbe fare il trucco ... impostare la famiglia di indirizzi.

import socket 
s = socket.socket(family=socket.AF_INET6) 
s.bind(('::1', 1234)) 
3

Se si vuole veramente una vasta soluzione, si potrebbe estendere la soluzione di utilizzare getaddrinfo():

import socket 
l = socket.getaddrinfo(None, "", 0, socket.SOCK_STREAM, 0, socket.AI_PASSIVE) 
for i in l: print i 

Questo dà

(2, 1, 6, '', ('0.0.0.0', 0)) 
(10, 1, 6, '', ('::', 0, 0, 0)) 

Questi sono i parametri si dovrebbe creare un socket con :

s = socket.socket(i[0], i[1], i[2]) 
if i[0] == AF_INET6: s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1) 
s.bind(i[4]) 

Ora avete tutti i socket che avete e potete usarli. (Ahimè, il IPV6_V6ONLY non funziona con le versioni di Windows meno recenti ...)

Se si dispone di un determinato nome host/IP per legarsi a, fare

l = socket.getaddrinfo("mylocalIP", None, 0, socket.SOCK_STREAM, 0, socket.AI_PASSIVE) 

e sceglieranno l'indirizzo corretto/famiglia di protocolli per voi:

>>> socket.getaddrinfo("::1", None, 0, socket.SOCK_STREAM, 0, socket.AI_PASSIVE) 
[(10, 1, 6, '', ('::1', 0, 0, 0))] 
>>> socket.getaddrinfo("127.0.0.1", None, 0, socket.SOCK_STREAM, 0, socket.AI_PASSIVE) 
[(2, 1, 6, '', ('127.0.0.1', 0))] 
>>> socket.getaddrinfo("localhost", None, 0, socket.SOCK_STREAM, 0, socket.AI_PASSIVE) 
[(10, 1, 6, '', ('::1', 0, 0, 0)), (2, 1, 6, '', ('127.0.0.1', 0))] 
>>> socket.getaddrinfo("192.168.1.32", None, 0, socket.SOCK_STREAM, 0, socket.AI_PASSIVE) 
[(2, 1, 6, '', ('192.168.1.32', 0))] 

ecc

2 vs 10 sono AF_INET vs. AF_INET6; socket.AI_PASSIVE significa che è necessario questo indirizzo per bind() ing.

Problemi correlati