【问题标题】:How to set timeout for urllib2.OpenDirector open() method如何为 urllib2.OpenDirector open() 方法设置超时
【发布时间】:2012-07-04 10:43:11
【问题描述】:

我正在使用一些 urllib2.HTTPHandler 子类作为 socksipy project 的代理。

除了遇到挂起的 URL 时,一切都可以正常工作。全局和通过 OpenDirector.open() 方法设置超时不会做任何事情。

这里是 urllib2.HTTPHandlers:

# get the socksipy project code
import socks

class SocksiPyConnection(httplib.HTTPConnection):
    def __init__(self, proxytype, proxyaddr, proxyport = None, rdns = False, username = None, password = None, *args, **kwargs):
        self.proxyargs = (proxytype, proxyaddr, proxyport, rdns, username, password)
        httplib.HTTPConnection.__init__(self, *args, **kwargs)

    def connect(self):
        self.sock = socks.socksocket()
        self.sock.setproxy(*self.proxyargs)
        if isinstance(self.timeout, float):
            self.sock.settimeout(self.timeout)
        self.sock.connect((self.host, self.port))

class SocksiPyHandler(urllib2.HTTPHandler):
    def __init__(self, *args, **kwargs):
        self.args = args
        self.kw = kwargs
        urllib2.HTTPHandler.__init__(self)

    def http_open(self, req):
        def build(host, port=None, strict=None, timeout=0):
            conn = SocksiPyConnection(*self.args, host=host, port=port, strict=strict, timeout=timeout, **self.kw)
            return conn
        return self.do_open(build, req)

我尝试将超时全局设置为 socket.setdefaulttimeout(30),但没有成功。当我在上面实例化 SocksiPyConnection 时,我也尝试过设置超时。最后,我尝试使用 OpenDirector.open 方法 as the API says it takes a timeout 设置超时,但没有成功。

挂起的测试代码:

import sys
# import socksipy base code
sys.path.append( "/parent/path/to/socks.py" )
import socks 
import urllib2
import socket
socket.setdefaulttimeout(30)
proxyhost = "responder.w2"
proxyport = 1050
sys.path.append( "/home/gcorradini" )
from sock_classes import SocksiPyHandler
opener = urllib2.build_opener(SocksiPyHandler(socks.PROXY_TYPE_SOCKS5, proxyhost, int(proxyport)) )
resp = opener.open("http://erma.orr.noaa.gov/cgi-bin/mapserver/charts?version=1.1.1&service=wms&request=GetCapabilities", timeout=30.0)
# i just hang here forever

【问题讨论】:

  • 它说:在 2.6 版中更改:添加了超时。你用的是哪个版本?
  • 我也在研究这个主题。我已经讨论过这个超时控制连接超时而不是读/写空闲超时。当我试图挖掘更多信息时,我发现了这个关于这个问题的旧帖子。 gossamer-threads.com/lists/python/python/563167

标签: python settimeout urllib2


【解决方案1】:

原来我上面提到的“挂起/超时”问题实际上是sockssipy socks.py 代码中的“阻塞”问题。如果您访问的端点仍然以 200 响应但不发送数据(0 字节),那么 socks.py 将阻塞,因为这就是它的写入方式。以下是创建自己的超时之前和之后:

socks.py 之前

def __recvall(self, bytes):
    """__recvall(bytes) -> data
    Receive EXACTLY the number of bytes requested from the socket.
    Blocks until the required number of bytes have been received.
    """
    data = ""
    while len(data) < bytes:
       data = data + self.recv(bytes-len(data))
    return data

socks.py 后超时

def __recvall(self, bytes):
    """__recvall(bytes) -> data
    Receive EXACTLY the number of bytes requested from the socket.
    Blocks until the required number of bytes have been received.
    """
    data = self.recv(bytes, socket.MSG_WAITALL)
    if type(data) not in (str, unicode) or len(data) != bytes:
        raise socket.timeout('timeout')
    return data

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    • 2016-09-24
    • 1970-01-01
    相关资源
    最近更新 更多