【问题标题】:What does ECONNABORTED mean when trying to connect a socket?尝试连接套接字时 ECONNABORTED 是什么意思?
【发布时间】:2012-03-11 07:06:19
【问题描述】:

我在 ubuntu 机器上使用 python 2.7。

客户端尝试连接到服务器。我得到了一个 EINPROGRESS,这是非阻塞套接字所期望的。

为了检查连接是否成功,我按照 {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} 的手册页中。什么意思?

【问题讨论】:

  • 即使你让这个工作,如果我是你,我不会这样做。我不知道套接字 API 在技术上是否允许重用以前连接失败的套接字,但是虽然 Linux 似乎并不介意,但我在 MacOS 上得到了 EINVAL。每次打开一个新套接字。

标签: python sockets


【解决方案1】:

ECONNABORTED 设置在 Linux Kernel Source Socket Code 的两个位置。

根据 errno 手册页和 /include/asm-generic/errno.h

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

first 位于 /net/socket.c 中定义系统调用 accept4 的函数中。

相关源代码

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

second 位于 /net/ipv4/af_inet.c 中定义符号 inet_stream_connect 的函数中。

相关源代码

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;

逻辑的相关解释如下。

inet_stream_connect 中,唯一可以转到sock_error 标签的代码是检查套接字是否被RST、超时、另一个进程或错误关闭。

sock_error 标签中 如果我们能恢复一个socket错误报告,就这样做,否则错误状态为ECONNABORTED

喜欢Celada的评论我也建议每次都打开一个新的socket。

【讨论】:

  • 甜蜜。我不知道 linux 内核有很多 goto :)。我曾经发现“软件导致连接中止”的信息完全不足,但根据您引用的代码,它更有意义。我认为第二个适用于我的情况。然后我会创建新的套接字,没问题。
【解决方案2】:

请参阅 errno 的手册页。在 FreeBSD 上,您可以找到它为 intro(2)。它说:

53 ECONABORTED 软件导致连接中止。主机内部导致连接中止。

至于为什么会发生这种情况,您必须在 Linux 内核源代码中查找套接字。仅在 FreeBSD 上 accept 似乎返回 ECONNABORTED。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    相关资源
    最近更新 更多