2012-03-10 106 views
6

私はubuntuマシンでPython 2.7を使用しています。ソケットを接続しようとしたときにECONNABORTEDとは何ですか?

クライアントがサーバーに接続しようとしています。私は、非ブロッキングソケットに期待されるEINPROGRESSを取得します。

は、接続が成功したかどうかを確認するために、私は{}の接続のためのmanページが示唆するものを実行します。

# 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}のmanページにありません。どういう意味ですか?

+1

これがうまく動作しても、私があなただったら私はやりません。以前ソケットAPIを技術的に再利用できるかどうかはわかりませんが、Linuxは気にしないようですが、MacOSではEINVALを取得しています。毎回新しいソケットを開きます。 – Celada

答えて

11

ECONNABORTEDは、Linuxカーネルソースソケットコードの2箇所に設定されています。

errno manページを1として

/include/asm-generic/errno.h

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

first/ネット/ソケットでシステムコールaccept4を定義する関数です。 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   } 

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

userspaceからのピアソケットのアドレスが と定義されていて、新しいソケットに名前がない場合は、エラー状態をECONNABORTEDに設定し、ラベルout_fdに移動します。

secondは、記号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; 

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

inet_stream_connectsock_errorラベルに移動している唯一のコードは、ソケットがRST、タイムアウト、別のプロセスまたはエラーによって閉じられたかどうかを確認することです。 Celadaのコメントと同様にECONNABORTED

からsock_errorラベル で

我々はソケットのエラーレポートを回復することができた場合は、そう、そうでない場合はエラー状態Iはまた、新しいソケットを毎回開いてお勧めします。

+0

甘い。私はLinuxカーネルが多くのものを持っていたのかどうか分からなかった:)。私は "ソフトウェアが接続を中断させた"ことを完全に情報量の少ないものにしていましたが、あなたが引用したコードに照らして、それは意味があります。私は2番目が私の場合に当てはまると思います。私は新しいソケットを作成します。問題はありません。 – Niriel

0

errnoのマニュアルページを参照してください。 FreeBSDでは、それをintro(2)と見なすことができます。それは言う:

53 ECONNABORTEDソフトウェアが接続を中断させた。ホストマシンの内部で接続が中止されました。

なぜこのようなことが起こるかについては、Linuxカーネルソースでソケットを調べる必要があります。 FreeBSDではacceptがECONNABORTEDと表示されます。

関連する問題