1. ホーム
  2. python

[解決済み] ソケットを接続しようとするとECONNABORTEDが表示されますが、どういう意味ですか?

2022-02-02 03:29:04

質問

ubuntuマシンでpython2.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が出ました。 ここまでは順調です。

接続に失敗したとき、何度か再試行したい。

問題点 2回目に同じソケットに接続しようとすると、{connect}からECONNABORTEDが送信されます。 これは{connect}のマニュアルページにはありません。 これはどういう意味ですか?

解決方法は?

ECONNABORTED は、Linux Kernel Source Socket Codeの2箇所に設定されています。

のように errno マンページと /include/asm-generic/errno.h

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

第一 は、システムコールを定義する関数にあります。 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;

関連するロジックの説明は以下の通りです。

へのgotoを持つ唯一のコードです。 sock_error のラベルを inet_stream_connect は、ソケットがRST、タイムアウト、他のプロセス、またはエラーによって閉じられたかどうかを確認するためのチェックです。

には sock_error ラベル ソケットエラーレポートを回復できる場合はそうし、そうでない場合はエラー状態から ECONNABORTED

のように セラーダ のコメントにあるように、私も毎回新しいソケットを開くことをお勧めします。