Ошибка ввода-вывода (ошибка сокета): [Errno 111] соединение отказано

У меня есть программа, которая использует urllib для периодического получения url-адреса, и я вижу прерывистый ошибки, как :

ошибка ввода-вывода (ошибка сокета): [Errno 111] соединение отказано.

он работает 90% времени, но othe r10% он терпит неудачу. Если повторите попытку выборки сразу после сбоя, она завершится успешно. Я не могу понять, почему это так. Я попытался увидеть, доступны ли какие-либо порты, и они есть. Есть идеи по отладке?

для получения дополнительной информации, трассировка стека есть:

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

Edit-поиск google не очень полезен, то, что я получил из него, это то, что сервер Я получаю иногда отказывается от соединений, как я могу проверить, что это не ошибка в моем коде и это действительно так?

5 ответов


используйте сниффер пакета как Wireshark посмотреть, что происходит. Вы должны увидеть SYN-помеченный пакет исходящий, SYN+ACK-помеченный входящий, а затем ACK-помеченный исходящий. После этого порт считается открытым с местной стороны.

Если вы видите только первый пакет и сообщение об ошибке приходит после нескольких секунд ожидания, другая сторона не отвечает вообще (как в: отключенный кабель, перегруженный сервер, ошибочный пакет был отброшен) и ваш локальный сетевой стек прерывает попытку подключения. Если вы видите первые пакеты, хост фактически отрицает соединение. Если вы видите "недостижимый порт ICMP" или хост недостижимых пакетов, брандмауэр или целевой хост информируют вас о том, что порт фактически закрыт.

конечно, вы не можете ожидать, что сервис будет доступен в любое время (рассмотрим все точки отказа между вами и данными), поэтому вы должны попробовать еще раз позже.


получение econnrefused errno означает, что код ядру было отказано в подключении на другом конце, поэтому, если это ошибка, она либо в вашем ядре, либо на другом конце. То, что вы можете сделать, это поймать ошибку очень определенным образом и попробовать еще раз через некоторое время, так как это, кажется, работает:

# 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")

замените две константы all-caps вашими любимыми числами.


у меня ранее была эта проблема с моим экземпляром EC2 (я обслуживал couchdb для обслуживания ресурсов-рассматриваю S3 Amazon в будущем).

одна вещь, которую нужно проверить (предполагая Ec2), заключается в том, что порт couchdb добавляется к вашим открытым портам в вашей политике безопасности.

Я конкретно столкнулся

"[Errno 111] соединение отказано"

над EC2, когда экземпляр был остановлен и запущен. Проблема, похоже, в том, что гонки-файла. Решением для меня было убийство couchdb (полностью и правильно) через:

pkill -f couchdb

и после перезагрузки с:

/etc/init.d/couchdb restart

Я не совсем уверен, что вызывает это. Ты можешь попробовать заглянуть в свой socket.py (у меня другая версия, поэтому номера строк из трассировки не совпадают, и я боюсь, что некоторые другие детали могут также не совпадать).

в любом случае, кажется хорошей практикой поместить ваш url-адрес в try: ... except: ... блок, и обработайте это с короткой паузой и повторной попыткой. URL, который вы пытаетесь получить, может быть отключен или слишком загружен, и это то, что вы сможете обрабатывать только с помощью в любом случае повтора.


Кажется, что сервер работает неправильно, поэтому убедитесь, что с терминалом по

telnet ip port

пример

telnet localhost 8069

вернет подключен к localhost таким образом, это указывает на то, что нет никаких проблем с подключением Иначе он вернется соединение отклонено это указывает на то, что есть проблема с подключением