8

1 週間ほど前、StackOverflow の誰かが、IPv6 リンクローカル アドレスに接続するための Python コードが機能しない理由を尋ねました desired local-interface-name is) ターゲット IP アドレスのサフィックス。私は自分が話していることを知っていると思っていたので、答える前に自分の提案を実際にテストしませんでした (恥ずかしい!)。

今日、私は同じテクニックを自分自身で使用しようとしましたが、うまくいかないようです. :^( つまり、このコードは機能しません:

>>> from socket import *
>>> s = socket(AF_INET6, SOCK_STREAM)
>>> s.connect(('fe80::21f:5bff:fe3f:1b36%en0', 2001))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in connect
socket.error: [Errno 65] No route to host

一方、次のコードは機能します (%en0 サフィックスの有無にかかわらず)。

>>> from socket import *
>>> s = socket(AF_INET6, SOCK_STREAM)
>>> s.connect(('fe80::21f:5bff:fe3f:1b36%en0', 2001, 0, 6))
>>> 

...しかし、最後の引数に指定するスコープID整数を把握するために、あまり移植性のないコードを実行してローカルインターフェイスを反復処理する必要があるため、そのようにするのは好きではありませんリストを作成し、「en0」という名前のインターフェイスを見つけて、そのスコープ ID を抽出します。これは、必要以上に複雑なオーバーヘッドになります。

connect() が IP アドレスへの %en0 サフィックスを受け入れているとすれば、スコープ ID を決定するために実際にそれを期待どおりに使用しないのはなぜですか?

FWIW、私は MacOS/X 10.6.4 の下で Python 2.6.1 でテストしています。

4

1 に答える 1

13

これは、ipv6 接続を行う正しい方法です。

>>> addrinfo = getaddrinfo('fe80::225:ff:fecd:5aa0%en0', 2001, AF_INET6, SOCK_STREAM)
>>> addrinfo
[(30, 1, 6, '', ('fe80::225:ff:fecd:5aa0%en0', 2001, 0, 4))]
>>> (family, socktype, proto, canonname, sockaddr) = addrinfo[0]
>>> s = socket(family, socktype, proto)
>>> s.connect(sockaddr)

getaddrinfo()は、正しい数値スコープとフロー情報を返します。

于 2010-10-27T06:33:45.700 に答える