我想在python上创建Ipv6套接字,我这样做:
#!/usr/bin/env python
import sys
import struct
import socket
host = 'fe80::225:b3ff:fe26:576'
sa = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sa.bind((host , 50000))
但失败了:
socket.error: (22, 'Invalid argument') ?
有人能帮我吗?谢谢!
我这样重做,但还是不行
>>>host = 'fe80::225:b3ff:fe26:576'
>>>sa = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
>>>res = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_DGRAM, 0, socket.AI_PASSIVE)
>>>family, socktype, proto, canonname, sockaddr = res[0]
>>>print sockaddr
('fe80::225:b3ff:fe26:576', 50001, 0, 0)
>>>sa.bind(sockaddr)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<string>", line 1, in bind
socket.error: (22, 'Invalid argument')
上面缺少的另一点是fe80::*是链接本地地址,因此在技术上没有作用域ID就不能使用它们。
如果没有接收,“
link-local
”意味着地址只能在特定链接上使用,但推论是,由于地址在理论上是特定于链接的,所以可以在多个链接上使用相同的地址。现在假设在大多数情况下,通过将链接本地地址转换为EUI-64,然后在U/L位(see)上翻转,可以从已经存在的唯一硬件(EUI-48)地址生成链接本地地址,但这并不是生成链接本地地址的唯一方法,其他机制可能导致重新使用该地址(我不认为任何事情都禁止这样做)。所以现在你知道为什么没用了。
下一个问题是如何修复它,或者从何处获取作用域ID。不幸的是,这并不明显。如果您阅读讨论“
Scope
”的IPV6 rfc,您会发现它是以一般方式定义的。实际上,如果您是在Linux(可能也是Windows/Mac?)中运行此代码的话您可以使用接口索引。请注意,目前nss mdns中有一个bug,即:本地名称返回的作用域id始终为零,因此在Linux中使用。本地名称基本上不起作用,除非您的代码已经计算出作用域id并自行设置。
这个问题有两个部分
第一期
您应该使用sa.bind(sockaddr),其中sockaddr是从getaddrinfo获得的
第二期
如果您查看socket文档中提供的示例,请访问
Socket接受三个参数
根据文件
如果使用getaddressinfo获取proto的值,则该值与默认值0不同
但是当我执行下面的操作时,我得到了一个不同的协议值-17。 你可能也想调查一下。
当然,socket.has_ipv6对我来说是真的。
相关问题 更多 >
编程相关推荐