Ошибка ввода / вывода (ошибка сокета): [Errno 111] Соединение отклонено - PullRequest
12 голосов
/ 01 апреля 2010

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

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

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

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

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

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

Ответы [ 5 ]

36 голосов
/ 01 апреля 2010

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

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

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

10 голосов
/ 01 апреля 2010

Получение 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")

Замените две константы всех заглавных букв вашими любимыми числами.

3 голосов
/ 26 января 2012

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

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

Я специально столкнулся

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

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

pkill -f couchdb

и затем перезапуск с:

/etc/init.d/couchdb restart
2 голосов
/ 01 апреля 2010

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

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

1 голос
/ 22 июня 2017

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

telnet ip port

пример

telnet localhost 8069

Будет возвращено подключено к localhost , поэтому оно указывает на отсутствие проблем с подключением В противном случае он вернет Отказано в соединении Это указывает на проблему с соединением

...