[英]Timeout not working using urllib2, socks5 proxy and socksipy
我在Python 2.6中將ocklib和urllib2一起使用。 一切正常,除了我碰到一個懸掛URL的超時之外。 urllib2函數超時參數或全局套接字默認超時均無效。 我什至嘗試在下面的子處理程序中以多種不同方式設置超時,但沒有成功。 有任何想法嗎?
這是一個測試腳本(假設您已經安裝了socksipy項目並將其添加到系統路徑中):
import os, sys
import httplib
sys.path.append( "/parent/path/to/socksipy/project" )
import socks # import socksipy
import socket
socket.setdefaulttimeout(30.0)
import urllib2
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)
if __name__ == '__main__':
#
# this one works for non-hanging URL
#
proxyhost = "responder.w2"
proxyport = 1050
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, proxyhost, int(proxyport))
socket.socket = socks.socksocket
resp = urllib2.urlopen("http://www.google.com", timeout=30.0)
# hang here
print "returned 1"
#
# one way to go about it for a hanging URL
#
proxyhost = "responder.w2"
proxyport = 1050
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, proxyhost, int(proxyport))
socket.socket = socks.socksocket
resp = urllib2.urlopen("http://erma.orr.noaa.gov/cgi-bin/mapserver/charts?version=1.1.1&service=wms&request=GetCapabilities", timeout=30.0)
# it hangs here
print "returned 2"
#
# another way to go about it for hanging URL
#
proxyhost = "responder.w2"
proxyport = 1050
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)
# it hangs here
print "returned 3"
這對我有用:
socks.socket.setdefaulttimeout(7)
您應該避免直接編輯python襪子庫。
事實證明,我上面提到的“掛起/超時”問題實際上是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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.