socket.shutdown vs socket.close
-
03-07-2019 - |
質問
最近、次のようなコードを見ました(もちろん、sockはソケットオブジェクトです):
sock.shutdown(socket.SHUT_RDWR)
sock.close()
ソケットでshutdownを呼び出して閉じた目的は何ですか?違いがある場合、このソケットは非ブロッキングIOに使用されています。
解決
1つの説明:
ソケットが不要になったら、 呼び出し元プログラムは破棄できます 閉じるサブルーチンを適用してソケット ソケット記述子に。もし 信頼できる配信ソケットにデータがあります クローズにかかるときに関連付けられます 場所、システムは試み続けます データ転送。ただし、データが まだ配信されていないため、システムは破棄します データ。アプリケーションは プログラムには保留中の用途はありません データ、シャットダウンを使用できます ソケットの前のサブルーチン 閉じます。
他のヒント
close
および shutdown
を呼び出すと、基になるソケットに2つの異なる影響があります。
最初に指摘するのは、ソケットが基本OSのリソースであり、複数のプロセスが同じ基本ソケットのハンドルを持つことができることです。
close
を呼び出すと、ハンドルカウントが1つ減り、ハンドルカウントがゼロに達すると、ソケットと関連する接続は通常のクローズ手順を実行します(実質的にFIN / EOFをピア)とソケットの割り当てが解除されます。
ここで注意することは、別のプロセスがまだソケットへのハンドルを持っているためにハンドル数がゼロにならない場合、接続は閉じられず、ソケットは割り当て解除されないことです。
一方、読み取りおよび書き込みのために shutdown
を呼び出すと、基礎となる接続が閉じられ、ソケットへのハンドルを持つプロセスの数に関係なく、FIN / EOFがピアに送信されます。ただし、ソケットの割り当ては行わないため、後で閉じる必要があります。 シャットダウンとクローズの説明:グレースフルシャットダウン(msdn)
Shutdown(あなたの場合)は、接続のもう一方の端に、ソケットからの読み取りまたはソケットへの書き込みを行う意思がないことを示します。次に、ソケットに関連付けられているメモリをすべて解放します。
シャットダウンを省略すると、接続が正常に閉じられるまでソケットがOSスタックに残る場合があります。
IMOの名前「shutdown」と「close」は誤解を招きやすく、「close」と「destroy」は違いを強調します。
Socket Programming HOWTO( py2 / < a href = "http://docs.python.org/3/howto/sockets.html#disconnecting" rel = "noreferrer"> py3 )
切断
厳密に言えば、ソケットを
close
する前にshutdown
を使用することになっています。shutdown
は、もう一方の端のソケットへの勧告です。渡す引数に応じて、&#8220; 私はもう送信しませんが、私はまだ聞きます&#8221;または&#8220 ; 私は聞いていません、良い馬鹿です!&#8221;。 ただし、ほとんどのソケットライブラリは、このエチケットの使用を怠っているプログラマに非常に使用されるため、通常はclose
はshutdown()と同じです。 close()
。 そのため、ほとんどの場合、明示的なシャットダウンは必要ありません。...
このコードは間違っていませんか?
シャットダウンコールの直後のクローズコールにより、カーネルはすべての発信バッファーを破棄します。
によると http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable 読み取りから0が返されるまで、シャットダウンから終了まで待機する必要があります。
シャットダウンにはいくつかの種類があります: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.shutdown.aspx 。 * nixも同様です。
Shutdown(1)、ソケットにデータを送信させない
これは次の場合に便利です
1-バッファーフラッシュ
2-奇妙なエラー検出
3-安全な保護
AからBにデータを送信するとき、それが保証されるわけではありません。 Bに送信され、A osバッファに送信されることが保証されているだけです。 順番にB osバッファーに送信します
Aでshutdown(1)を呼び出すと、Aのバッファーがフラッシュされ、エラーが発生します バッファが空でない場合、つまり、データがまだピアに送信されていない場合
ただし、これは取り返しのつかないものです。 すべてのデータを送信したので、少なくともピアにあることを確認したい osバッファ