Что означает ECONNABORTED при попытке подключения сокета? - PullRequest
6 голосов
/ 10 марта 2012

Я использую Python 2.7 на машине с Ubuntu.

Клиент пытается подключиться к серверу.Я получаю EINPROGRESS, который ожидается для неблокирующих сокетов.

Чтобы проверить, успешно ли установлено соединение, я делаю то, что предлагает страница man для {connect}:

# EINPROGRESS The socket is nonblocking and the connection cannot be
# completed immediately.  It is possible to select(2) or poll(2) for
# completion by selecting the socket for writing.  After select(2)
# indicates writability, use getsockopt(2) to read the SO_ERROR option at
# level SOL_SOCKET to determine whether connect() completed successfully
# (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual error
# codes listed here, explaining the reason for the failure)

сервер находится в автономном режиме, это дает мне ECONNREFUSED.Пока все хорошо.

Когда соединение не удается, я хочу повторить попытку несколько раз.

Проблема : во второй раз я пытаюсь подключить тот же сокет,{connect} отправляет мне сообщение.Этого нет в справочной странице {connect}.Что это значит?

Ответы [ 2 ]

13 голосов
/ 11 марта 2012

ECONNABORTED устанавливается в двух местах исходного кода сокета ядра Linux.

Согласно справочной странице errno и / include / asm-generic / errno.h

#define ECONNABORTED 103 /* Software caused connection abort */

first находится в функции, которая определяет системный вызов accept4 в / net / socket.c .

Соответствующий исходный код

1533         if (upeer_sockaddr) {
1534                 if (newsock->ops->getname(newsock, (struct sockaddr *)&address,
1535                                           &len, 2) < 0) {
1536                         err = -ECONNABORTED;
1537                         goto out_fd;
1538                 }
1539                 err = move_addr_to_user((struct sockaddr *)&address,
1540                                         len, upeer_sockaddr, upeer_addrlen);
1541                 if (err < 0)
1542                         goto out_fd;
1543         }

Соответствующее объяснение логики приведено ниже.

Если адрес равноправного сокета из пространства пользователя определен и Еслиновый сокет не имеет имени, затем установите состояние ошибки ECONNABORTED и перейдите к метке out_fd.

секунда находится в функции, которая определяет символ inet_stream_connect в / net / ipv4 / af_inet.c .

Соответствующий исходный код

645         /* Connection was closed by RST, timeout, ICMP error
646          * or another process disconnected us.
647          */
648         if (sk->sk_state == TCP_CLOSE)
649                 goto sock_error; 

662 sock_error:
663         err = sock_error(sk) ? : -ECONNABORTED;
664         sock->state = SS_UNCONNECTED;
665         if (sk->sk_prot->disconnect(sk, flags))
666                 sock->state = SS_DISCONNECTING;
667         goto out;

Соответствующее объяснение логики приведено ниже.

Единственный код, который имеет переход к метке sock_error в inet_stream_connect, - это проверка того, был ли сокет закрыт RST, тайм-аут, другим процессом или ошибкой.

В sock_error этикетка Если мы можемвосстановить отчет об ошибке сокета, сделайте это, в противном случае состояние ошибки до ECONNABORTED

Как и комментарий Celada , я также рекомендую каждый раз открывать новый сокет.

0 голосов
/ 10 марта 2012

См. Страницу руководства для errno.На FreeBSD вы можете найти его как intro (2).Там написано:

53 ECONNABORTED Программное обеспечение вызвало прерывание соединения.Внутреннее соединение с вашим хост-компьютером вызвано прерыванием соединения.

Что касается того, почему это происходит, вам придется искать в источнике ядра Linux сокеты.В FreeBSD только accept кажется возвращенным ECONNABORTED.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...