Python handling socket.error: [Errno 104] Connection reset by peer

匿名 (未验证) 提交于 2019-12-03 02:44:02

问题:

When using Python 2.7 with urllib2 to retrieve data from an API, I get the error [Errno 104] Connection reset by peer. Whats causing the error, and how should the error be handled so that the script does not crash?

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

Traceback (most recent call last):   File "/var/www/testApp/python/ticker.py", line 71, in      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 

回答1:

"Connection reset by peer" is the TCP/IP equivalent of slamming the phone back on the hook. It's more polite than merely not replying, leaving one hanging. But it's not the FIN-ACK expected of the truly polite TCP/IP converseur. (From other SO answer)

So you can't do anything about it, it is the issue of the server.

But you could use try .. except block to handle that exception:

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. 


回答2:

You can try to add some time.sleep calls to your code.

It seems like the server side limits the amount of requests per timeunit (hour, day, second) as a security issue. You need to guess how many (maybe using another script with a counter?) and adjust your script to not surpass this limit.

In order to avoid your code from crashing, try to catch this error with try .. except around the urllib2 calls.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!