Eva*_*ran 11 python mechanize urllib ipv6
这是一个相关的问题,但我无法弄清楚如何应用mechanize/urllib2的答案:如何强制python httplib库只使用A请求
基本上,给出这个简单的代码:
#!/usr/bin/python
import urllib2
print urllib2.urlopen('http://python.org/').read(100)
Run Code Online (Sandbox Code Playgroud)
这导致wireshark说以下内容:
0.000000 10.102.0.79 -> 8.8.8.8 DNS Standard query A python.org
0.000023 10.102.0.79 -> 8.8.8.8 DNS Standard query AAAA python.org
0.005369 8.8.8.8 -> 10.102.0.79 DNS Standard query response A 82.94.164.162
5.004494 10.102.0.79 -> 8.8.8.8 DNS Standard query A python.org
5.010540 8.8.8.8 -> 10.102.0.79 DNS Standard query response A 82.94.164.162
5.010599 10.102.0.79 -> 8.8.8.8 DNS Standard query AAAA python.org
5.015832 8.8.8.8 -> 10.102.0.79 DNS Standard query response AAAA 2001:888:2000:d::a2
Run Code Online (Sandbox Code Playgroud)
这是一个5秒的延迟!
我的系统中没有启用IPv6(gentoo编译USE=-ipv6
)所以我不认为python有任何理由甚至尝试IPv6查找.
上面引用的问题建议明确设置AF_INET
听起来很棒的套接字类型.我不知道如何强制urllib或机械化使用我创建的任何套接字.
编辑:我知道AAAA查询是问题,因为其他应用程序也有延迟,一旦我禁用ipv6重新编译,问题就消失了......除了仍在执行AAAA请求的python中.
And*_*ner 16
遇到同样的问题,根据JJ提供的信息,这是一个丑陋的黑客(使用风险自负......).
这基本上强制family
的参数socket.getaddrinfo(..)
,以socket.AF_INET
代替使用socket.AF_UNSPEC
(零,这似乎是在使用socket.create_connection
),不仅从通话urllib2
,但应该将所有来电做到这一点socket.getaddrinfo(..)
:
#--------------------
# do this once at program startup
#--------------------
import socket
origGetAddrInfo = socket.getaddrinfo
def getAddrInfoWrapper(host, port, family=0, socktype=0, proto=0, flags=0):
return origGetAddrInfo(host, port, socket.AF_INET, socktype, proto, flags)
# replace the original socket.getaddrinfo by our version
socket.getaddrinfo = getAddrInfoWrapper
#--------------------
import urllib2
print urllib2.urlopen("http://python.org/").read(100)
Run Code Online (Sandbox Code Playgroud)
至少在这个简单的情况下,这对我有用.
当询问 python.org 的 AAAA 时,DNS 服务器 8.8.8.8(Google DNS)立即回复。因此,事实上我们在您发布的跟踪中没有看到此回复,这可能表明此数据包没有返回(UDP 会发生这种情况)。如果这种损失是随机的,那么这是正常的。如果是系统性的,则意味着您的网络设置存在问题,可能是防火墙损坏,导致第一个 AAAA 回复无法返回。
5 秒的延迟来自存根解析器。那么,如果是随机的,可能是运气不好,但与 IPv6 无关,A 记录的回复也可能失败。
禁用 IPv6 似乎是一个非常奇怪的举动,距离最后一个 IPv4 地址分配只有两年!
% dig @8.8.8.8 AAAA python.org
; <<>> DiG 9.5.1-P3 <<>> @8.8.8.8 AAAA python.org
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50323
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;python.org. IN AAAA
;; ANSWER SECTION:
python.org. 69917 IN AAAA 2001:888:2000:d::a2
;; Query time: 36 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sat Jan 9 21:51:14 2010
;; MSG SIZE rcvd: 67
Run Code Online (Sandbox Code Playgroud)