2012-03-10 23 views
6

Estoy usando python 2.7 en una máquina ubuntu.¿Qué significa ECONNABORTED cuando intenta conectar un socket?

El cliente intenta conectarse al servidor. Obtengo un EINPROGRESS que se espera para enchufes sin bloqueo.

Para comprobar si la conexión es correcta, hago lo que la página del manual para conectar} {sugiere:

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

Cuando el servidor está fuera de línea, esto me da una ECONNREFUSED. Hasta aquí todo bien.

Cuando la conexión falla, quiero volver a intentarlo varias veces.

Problema: la segunda vez que intento conectar ese mismo conector, {connect} me envía ECONNABORTED. Este no está en la página man de {connect}. Qué significa eso?

+1

Incluso si haces que esto funcione, si fuera tú, no lo haría. No sé si la API de sockets técnicamente permite reutilizar un socket que no se pudo conectar antes, pero aunque a Linux no parece importarle, obtengo EINVAL en MacOS. Abra un nuevo socket cada vez. – Celada

Respuesta

11

ECONNABORTED se establece en dos lugares del código de zócalo de origen del kernel de Linux.

De acuerdo con la página errno hombre y /include/asm-generic/errno.h

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

El first está en la función que define la syscall accept4 en /net/socket. c.

Relevante Código Fuente

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   } 

La explicación pertinente de la lógica está por debajo.

Si la dirección de la toma de pares de espacio de usuario se define y si el nuevo socket no tiene nombre, a continuación, establecer el estado de error a ECONNABORTED y Goto la etiqueta out_fd.

El second está en la función que define el símbolo inet_stream_connect en /net/ipv4/af_inet.c.

Relevante Código Fuente

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; 

La explicación pertinente de la lógica está por debajo.

El único código que tiene una entrada a la etiqueta sock_error en inet_stream_connect es la comprobación para ver si el socket se cerró por RST, tiempo de espera, otro proceso o error.

En la etiqueta Si podemos recuperar un informe de errores de conectores sock_error, lo hacen, de lo contrario el estado de error a ECONNABORTED

Como comentario Celada 's También recomiendo abrir un nuevo socket cada vez.

+0

Dulce. No tenía idea de que el kernel de Linux tenía muchos gotos :). Solía ​​encontrar que el "software causado por el aborto de la conexión" era totalmente poco informativo, pero a la luz del código que usted cita tiene más sentido. Creo que el segundo se aplica a mi caso. Crearé nuevos sockets entonces, no hay problema. – Niriel

0

Consulte la página del manual para errno. En FreeBSD puede encontrarlo como intro (2). Dice:

53 ECONNABORTED El software provocó la interrupción de la conexión. Se produjo un aborto de conexión interno a su equipo host.

En cuanto a por qué sucede esto, tendrías que buscar en la fuente del kernel de Linux los sockets. En FreeBSD, solo accept parece regresar ECONNABORTED.

Cuestiones relacionadas