Что означает ECONNABORTED при попытке подключения сокета?
Я использую 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} отправляет мне ECONNABORTED. Этого нет на главной странице {connect}. Что это значит?
2 ответов
ECONNABORTED
устанавливается в двух местах исходного кода сокета ядра Linux.
на errno
man page и / include/asm-generic / errno.h
#define ECONNABORTED 103 /* Software caused connection abort */
на первый находится в функции, которая определяет syscall 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
и goto метка out_fd
.
на второй находится в функции, которая определяет символ inet_stream_connect
на /нетто/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
- это проверка, чтобы увидеть, был ли сокет закрыт первым, таймаутом, другим процессом или ошибкой.
на sock_error
ярлык
Если мы можем восстановить отчет об ошибке сокета, сделайте это, иначе состояние ошибки ECONNABORTED
как Селадекомментарий я также рекомендую открывать новый сокет каждый раз.
см. страницу руководства для errno. На FreeBSD вы можете найти его как intro
(2). Он говорит:
53 программное обеспечение ECONNABORTED вызвало прерывание соединения. Прерывание соединения было вызвано внутренним для вашей хост-машины.
что касается того, почему это происходит, вам придется искать сокеты в источнике ядра Linux. Только на FreeBSD accept
Кажется, возврат ECONNABORTED.