2012-06-13 34 views
6

Anteriormente utilicé el siguiente código para vincular la dirección IPv4 al socket Python como dirección IP de origen.Enlazar la dirección IPv6 al socket Python como dirección IP de origen

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 

¿Funciona el código anterior para la dirección IPv6? Si no, ¿cómo puedo vincular una dirección IPv6?

¡Gracias de antemano!

Respuesta

6

puede probar esto, para obtener una dirección IPv6, es recomendable utilizar socket.getaddrinfo devolverá todas las diferentes direcciones IPv4 e IPv6, puede enlazar a todos ellos o simplemente, que cada vez que desea/necesitar.

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

Esto debería hacer el truco ... establecer la familia de direcciones.

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

Si realmente quieres una extensa solución, que podría ampliar su solución para utilizar getaddrinfo():

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

Esto da

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

Estos son los parámetros que debe crear 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]) 

Ahora tiene tantos enchufes como protocolos tiene y puede usarlos. (Por desgracia, el IPV6_V6ONLY no funciona bajo las versiones anteriores de Windows ...)

Si usted tiene un nombre de host determinado/IP para unirse a, hacer

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

y se elegirá la dirección correcta/familia de protocolos para usted:

>>> 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))] 

etc.

2 vs 10 son AF_INET vs AF_INET6; socket.AI_PASSIVE significa que necesita esta dirección para bind() ing.

Cuestiones relacionadas