2012-06-13 16 views
6

以前は、IPv4アドレスをソースIPアドレスとしてPythonソケットにバインドするために以下のコードを使用しました。IPv6アドレスをソースIPアドレスとしてPythonソケットにバインド

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 

上記のコードはIPv6アドレスで動作しますか?そうでない場合は、どのようにIPv6アドレスをバインドできますか?

ありがとうございます!

答えて

6

あなたはIPv6アドレスを取得するには、これを試すことができ、それはあなたがsocket.getaddrinfoを使用すること、それがすべて異なるアドレスIPv4とIPv6の両方を返しますお勧めです、あなたが欲しい、これまでどちらそれらすべてまたはちょうどをバインドすることができます/必要。

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

これは、トリックを行う必要があります...アドレスファミリを設定します。

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

あなたは本当に大規模なソリューションをしたい場合、あなたはgetaddrinfo()を使用するようにソリューションを拡張することができ:

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

これは

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

これらは、あなたがしてソケットを作成する必要がありますパラメータでありを提供します:

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

プロトコルを持っているソケットをいくつでも使用できます。あなたがにバインドするために与えられたホスト名/ IPを持って、

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

を行うと、それは/正しいアドレスを選択する場合は

(ああ、IPV6_V6ONLYは、古いバージョンのWindows ...の下では動作しません)あなたのためのプロトコルファミリ:10

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

など

2AF_INET対です; socket.AI_PASSIVEは、bind()にこのアドレスが必要です。

関連する問題