Python处理套接字。错误:[Errno 104]对等方重置连接

Python处理套接字。错误:[Errno 104]对等方重置连接,python,ubuntu,python-2.7,urllib2,Python,Ubuntu,Python 2.7,Urllib2,当使用Python2.7和urllib2从API检索数据时,我得到了错误[Errno 104]连接被对等方重置。导致错误的原因是什么?如何处理错误以使脚本不会崩溃 ticker.py def urlopen(url): response = None request = urllib2.Request(url=url) try: response = urllib2.urlopen(request).read() except urllib2.HT

当使用Python2.7和
urllib2
从API检索数据时,我得到了错误
[Errno 104]连接被对等方重置。导致错误的原因是什么?如何处理错误以使脚本不会崩溃

ticker.py

def urlopen(url):
    response = None
    request = urllib2.Request(url=url)
    try:
        response = urllib2.urlopen(request).read()
    except urllib2.HTTPError as err:
        print "HTTPError: {} ({})".format(url, err.code)
    except urllib2.URLError as err:
        print "URLError: {} ({})".format(url, err.reason)
    except httplib.BadStatusLine as err:
        print "BadStatusLine: {}".format(url)
    return response

def get_rate(from_currency="EUR", to_currency="USD"):
    url = "https://finance.yahoo.com/d/quotes.csv?f=sl1&s=%s%s=X" % (
        from_currency, to_currency)
    data = urlopen(url)
    if "%s%s" % (from_currency, to_currency) in data:
        return float(data.strip().split(",")[1])
    return None


counter = 0
while True:

    counter = counter + 1
    if counter==0 or counter%10:
        rateEurUsd = float(get_rate('EUR', 'USD'))

    # does more stuff here
回溯

Traceback (most recent call last):
  File "/var/www/testApp/python/ticker.py", line 71, in <module>
    rateEurUsd = float(get_rate('EUR', 'USD'))
  File "/var/www/testApp/python/ticker.py", line 29, in get_exchange_rate
    data = urlopen(url)
  File "/var/www/testApp/python/ticker.py", line 16, in urlopen
    response = urllib2.urlopen(request).read()
  File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 406, in open
    response = meth(req, response)
  File "/usr/lib/python2.7/urllib2.py", line 519, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python2.7/urllib2.py", line 438, in error
    result = self._call_chain(*args)
  File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 625, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "/usr/lib/python2.7/urllib2.py", line 406, in open
    response = meth(req, response)
  File "/usr/lib/python2.7/urllib2.py", line 519, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python2.7/urllib2.py", line 438, in error
    result = self._call_chain(*args)
  File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 625, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "/usr/lib/python2.7/urllib2.py", line 400, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 418, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1207, in http_open
    return self.do_open(httplib.HTTPConnection, req)
  File "/usr/lib/python2.7/urllib2.py", line 1180, in do_open
    r = h.getresponse(buffering=True)
  File "/usr/lib/python2.7/httplib.py", line 1030, in getresponse
    response.begin()
  File "/usr/lib/python2.7/httplib.py", line 407, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python2.7/httplib.py", line 365, in _read_status
    line = self.fp.readline()
  File "/usr/lib/python2.7/socket.py", line 447, in readline
    data = self._sock.recv(self._rbufsize)
socket.error: [Errno 104] Connection reset by peer
error: Forever detected script exited with code: 1
回溯(最近一次呼叫最后一次):
文件“/var/www/testApp/python/ticker.py”,第71行,在
汇率EURUD=浮动汇率(获取汇率('EUR','USD'))
文件“/var/www/testApp/python/ticker.py”,第29行,以获取汇率
数据=url打开(url)
文件“/var/www/testApp/python/ticker.py”,第16行,在urlopen中
response=urllib2.urlopen(request).read()
文件“/usr/lib/python2.7/urllib2.py”,第126行,在urlopen中
return\u opener.open(url、数据、超时)
文件“/usr/lib/python2.7/urllib2.py”,第406行,打开
响应=方法(请求,响应)
http_响应中的文件“/usr/lib/python2.7/urllib2.py”,第519行
“http”、请求、响应、代码、消息、hdrs)
文件“/usr/lib/python2.7/urllib2.py”,第438行出错
结果=自身调用链(*args)
文件“/usr/lib/python2.7/urllib2.py”,第378行,在调用链中
结果=func(*args)
http\u error\u 302中的文件“/usr/lib/python2.7/urllib2.py”,第625行
返回self.parent.open(新建,超时=请求超时)
文件“/usr/lib/python2.7/urllib2.py”,第406行,打开
响应=方法(请求,响应)
http_响应中的文件“/usr/lib/python2.7/urllib2.py”,第519行
“http”、请求、响应、代码、消息、hdrs)
文件“/usr/lib/python2.7/urllib2.py”,第438行出错
结果=自身调用链(*args)
文件“/usr/lib/python2.7/urllib2.py”,第378行,在调用链中
结果=func(*args)
http\u error\u 302中的文件“/usr/lib/python2.7/urllib2.py”,第625行
返回self.parent.open(新建,超时=请求超时)
文件“/usr/lib/python2.7/urllib2.py”,第400行,打开
响应=自身打开(请求,数据)
文件“/usr/lib/python2.7/urllib2.py”,第418行,打开
"开放",
文件“/usr/lib/python2.7/urllib2.py”,第378行,在调用链中
结果=func(*args)
文件“/usr/lib/python2.7/urllib2.py”,第1207行,在http\u open中
返回self.do_open(httplib.HTTPConnection,req)
文件“/usr/lib/python2.7/urllib2.py”,第1180行,打开
r=h.getresponse(缓冲=True)
getresponse中的文件“/usr/lib/python2.7/httplib.py”,第1030行
response.begin()
文件“/usr/lib/python2.7/httplib.py”,第407行,在begin中
版本、状态、原因=self.\u读取\u状态()
文件“/usr/lib/python2.7/httplib.py”,第365行,处于读取状态
line=self.fp.readline()
文件“/usr/lib/python2.7/socket.py”,第447行,在readline中
数据=self.\u sock.recv(self.\r bufsize)
socket.error:[Errno 104]对等方重置连接
错误:检测到脚本已退出,代码:1
“由对等方重置连接”是TCP/IP协议,相当于将手机重新挂上钩子。这比不回答、挂着一个电话更礼貌。但这并不是真正有礼貌的TCP/IP交谈者所期望的结果。()

所以你对此无能为力,这是服务器的问题

但是你可以用
试试。。除处理该异常的
块外:

from socket import error as SocketError
import errno

try:
    response = urllib2.urlopen(request).read()
except SocketError as e:
    if e.errno != errno.ECONNRESET:
        raise # Not error we are looking for
    pass # Handle error here.

您可以尝试向代码中添加一些
time.sleep
调用

服务器端似乎限制了每个时间单位(小时、天、秒)的请求量,这是一个安全问题。您需要猜测有多少(可能使用另一个带有计数器的脚本?)


为了避免代码崩溃,请尝试使用
try..捕获此错误。。除了urllib2调用周围的

有一种方法可以在带有ConnectionResetError的except子句中直接捕获错误,最好隔离正确的错误。 此示例还捕获超时

from urllib.request import urlopen 
from socket import timeout

url = "http://......"
try: 
    string = urlopen(url, timeout=5).read()
except ConnectionResetError:
    print("==> ConnectionResetError")
    pass
except timeout: 
    print("==> Timeout")
    pass

在arch linux上,get_rate对我来说很好。你确定你没有被过滤吗?你能在浏览器中加载该url吗?@korylprince它在浏览器中工作正常,脚本在错误开始出现之前运行了一段时间。如果我无法避免该错误,那么应该如何处理该错误以使其不会崩溃,并可能使用检索到的最新值?服务器管理员是否确实通常使用此方法阻止客户端的潜在刮取请求,或者更可能是一个无意中的错误?现在我想知道我是否被故意阻止了……在某些情况下,它可能是由于系统另一部分的错误而发生的。在我的例子中,在我的服务器端有许多CLOSE_WAIT tcp连接,并且数量超过了服务器应用程序所能提供的数量(java一次最多允许50个连接)。因此,我的服务器端应用程序只是在大约50个关闭等待挂起的连接后重置连接,从而拒绝新的连接尝试。不是母语为英语的人。“将手机重新挂上钩子”是什么意思?@Pinocchio我也不是母语人士,但这也存在于我的语言中,指的是过时的手机技术:对于旧手机,当你拿起手机时,钩子会自动打开连接。当你把电话放回钩子上时,它断开了。所以基本上在现代语言中,它的意思是“按下断开连接/红色按钮,离开呼叫”。因此,如果我可以控制服务器和客户端--我可以做什么来解决服务器端的问题?非常感谢。