I/O错误(套接字错误):[错误号111] 连接被拒绝
我有一个程序,它使用urllib定期获取一个网址,但我遇到了一些间歇性的错误,比如:
输入/输出错误(套接字错误):[错误号 111] 连接被拒绝。
这个程序90%的时间都能正常工作,但剩下的10%时间会失败。如果在失败后立即重试获取,它又能成功。我搞不清楚为什么会这样。我检查过可用的端口,都是正常的。有没有什么调试的建议?
补充信息,错误堆栈信息是:
File "/usr/lib/python2.6/urllib.py", line 203, in open
return getattr(self, name)(url)
File "/usr/lib/python2.6/urllib.py", line 342, in open_http
h.endheaders()
File "/usr/lib/python2.6/httplib.py", line 868, in endheaders
self._send_output()
File "/usr/lib/python2.6/httplib.py", line 740, in _send_output
self.send(msg)
File "/usr/lib/python2.6/httplib.py", line 699, in send
self.connect()
File "/usr/lib/python2.6/httplib.py", line 683, in connect
self.timeout)
File "/usr/lib/python2.6/socket.py", line 512, in create_connection
raise error, msg
编辑 - 我在谷歌搜索了一下,结果并不太有帮助,我了解到我获取的服务器有时会拒绝连接,我该如何确认这不是我代码中的错误,而确实是这种情况呢?
5 个回答
我之前在使用EC2实例时遇到过这个问题(我当时在用couchdb来提供资源——未来可能考虑使用亚马逊的S3)。
首先要检查的一点是(假设你在用EC2),确保couchdb的端口已经添加到你的安全策略中的开放端口里。
我具体遇到的问题是:
"[Errno 111] 连接被拒绝"
这个问题出现在EC2上,当实例被停止再启动时。问题似乎是因为pid文件的竞争。对我来说,解决办法是通过以下命令完全且正确地杀掉couchdb:
pkill -f couchdb
然后再用以下命令重新启动:
/etc/init.d/couchdb restart
收到一个ECONNREFUSED的错误代码,意味着你的系统在尝试连接时,被对方拒绝了。所以如果这是个问题,那可能是你这边的系统出了问题,或者对方的系统有问题。
你可以用一种很特别的方法来捕捉这个错误,然后稍等一会儿再试,因为这样似乎有效:
# This is Python > 2.5 code
import errno, time
for attempt in range(MAXIMUM_NUMBER_OF_ATTEMPTS):
try:
# your urllib call here
except EnvironmentError as exc: # replace " as " with ", " for Python<2.6
if exc.errno == errno.ECONNREFUSED:
time.sleep(A_COUPLE_OF_SECONDS)
else:
raise # re-raise otherwise
else: # we tried, and we had no failure, so
break
else: # we never broke out of the for loop
raise RuntimeError("maximum number of unsuccessful attempts reached")
把那两个全大写的常量换成你喜欢的数字就可以了。
可以使用像Wireshark这样的网络数据包嗅探工具来观察发生了什么。你需要看到一个带有SYN标志的出站数据包,然后是一个带有SYN+ACK标志的入站数据包,最后再看到一个带有ACK标志的出站数据包。完成这些后,端口就被认为是在本地是开放的。
如果你只看到第一个数据包,而在等待几秒后出现错误信息,这说明另一方根本没有回应(可能是:网线拔掉了、服务器过载、数据包被错误处理而丢弃)。这时,你本地的网络系统会放弃连接尝试。如果你看到RST数据包,这表示对方实际上拒绝了连接。如果你看到“ICMP端口不可达”或者主机不可达的数据包,这说明防火墙或者目标主机告诉你这个端口实际上是关闭的。
当然,你不能指望服务随时都可用(想想你和数据之间可能出现的各种问题),所以你应该稍后再试。