1

いくつかのPythonドキュメントを除いて、これに関するドキュメントは見つかりませんでした

18.1.4.2. タイムアウトと accept メソッド

getdefaulttimeout()でない場合Noneaccept()メソッドによって返されるソケットはそのタイムアウトを継承します。それ以外の場合、動作はリッスン ソケットの設定に依存します。

リスニング ソケットがブロッキング モードまたはタイムアウト モードの場合、 によって返されるソケットはaccept()ブロッキング モードです。

リッスンしているソケットが非ブロック モードの場合、返されるソケットがブロック モードか非ブロック モードかaccept()は、オペレーティング システムによって異なります。クロスプラットフォームの動作を確保したい場合は、この設定を手動でオーバーライドすることをお勧めします。

この [質問] を読みました:ソケット オプションは、リッスンしているソケットから accept() にわたって継承されますか? 、最終的には評決はまだ実装定義のままだと思います。プラットフォームでのテストは、各カーネルからソースを読み取るよりも簡単だと思います。

ここでは、タイムアウトオプションが継承されていることを明確に示しています。しかし、accept(2) のマンページには、これについての言及はありません。私のボックス (Embedded Linux ボックス) の 1 つでいくつかの C++ コードをデバッグしたとき、これは非常に衝撃的でした。受け入れられたソケットがこのオプションを継承しないことを期待していました。

この質問に対する決定的な答えはどこにありますか?

4

2 に答える 2

2

これが Python の質問ではなく C の質問である場合、Python のドキュメントに基づいSO_RCVTIMEOて継承されることに関して結論を​​出すことはありません。accept(2)いずれにせよ、Python のドキュメントを誤解している可能性があると思います。

  1. SO_RCVTIMEOオプションについて明示的に言及しない
  2. タイムアウト値がリッスン ソケットから継承されるとは決して言わず、むしろによって設定されたグローバル タイムアウト値から継承されますsetdefaulttimeout()

のソース コードを見ると、Python はsocket オプションsocketmodule.cさえ使用していません。SO_RCVTIMEO代わりに、ソケット オブジェクトの独自の内部表現にタイムアウト値を格納し、それをselect(2)およびの呼び出しで使用しますpoll(2)

Python のやや奇妙な実装の論理的根拠は、多くのプラットフォームで実行するように設計されており、そのうちのいくつかはSO_RCVTIMEOオプションをサポートしていないためだと思います。唯一の参照SO_RCVTIMEOは4773行目です...

#ifdef SO_RCVTIMEO
PyModule_AddIntConstant(m, "SO_RCVTIMEO", SO_RCVTIMEO);
#endif

SO_RCVTIMEO...コンパイルされたプラットフォームで定義されていない場合に備えて、プリプロセッサディレクティブで囲まれています。

なぜPythonのドキュメントが言うのか...

...メソッドによって返されるソケットは、accept()そのタイムアウトを継承します...

...これは、Python の内部実装によりaccept()、新しいソケットの内部タイムアウト値が 732 行目のデフォルトのタイムアウト値に明示的に設定されているためです...

s->sock_timeout = defaulttimeout;

元の質問については...

この質問に対する決定的な答えはどこにありますか?

...カーネルソースコードを見つけるまで探し回る必要があると思いますが、継承されるものについて何も仮定せず、親ソケット FD のデフォルトから変更したオプションを明示的にオーバーライドする方がおそらく簡単です。によって返された新しいソケット FD でaccept(2)

于 2013-04-25T13:06:35.970 に答える