I'm using python 2.7 on an ubuntu machine.
The client tries to connect to the server. I get a EINPROGRESS which is expected for non-blocking sockets.
To check whether or not the connection succeeded, I do what the man page for {connect} suggest:
# 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)
When the server is offline, this gives me a ECONNREFUSED. So far so good.
When the connection fails, I want to try again a few times.
Problem: the second time I try to connect that same socket, {connect} sends me ECONNABORTED. This one isn't in the man page of {connect}. What does it mean?
ECONNABORTED. The remote side aborted the connection before the accept () operation completed. The error message that you see in the EMS Server log most likely means that during the phase where the server accepts a connection from a client, the client has actually aborted the connection.
A socket is one endpoint of a two-way communication link between two programs running on the network. A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sent to. An endpoint is a combination of an IP address and a port number.
ECONNABORTED
is set in two places of the Linux Kernel Source Socket Code.
As per the errno
man page and /include/asm-generic/errno.h
#define ECONNABORTED 103 /* Software caused connection abort */
The first is in the function that defines the syscall accept4
in /net/socket.c.
Relevant Source Code
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 }
The relevant explanation of logic is below.
If the address of the peer socket from userspace is defined
and If the new socket doesn't have name, then set error state to ECONNABORTED
and goto the label out_fd
.
The second is in the function that defines the symbol inet_stream_connect
in /net/ipv4/af_inet.c.
Relevant Source Code
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;
The relevant explanation of logic is below.
The only code that has a goto to the sock_error
label in inet_stream_connect
is the check to see if the socket was closed by RST,timeout, another process or error.
In the sock_error
label
If we can recover a socket error report, do so , otherwise the error state to ECONNABORTED
Like Celada's comment I also recommend opening a new socket each time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With