最近、次のようなコードを少し見ました(もちろん、sockはソケットオブジェクトです)。
sock.shutdown(socket.SHUT_RDWR)
sock.close()
ソケットでシャットダウンを呼び出してから閉じることの正確な目的は何ですか?違いがある場合、このソケットは非ブロッキングIOに使用されています。
説明 :
ソケットが不要になったら、呼び出しプログラムは、ソケット記述子にクローズサブルーチンを適用することにより、ソケットを破棄できます。クローズが行われたときに信頼できる配信ソケットにデータが関連付けられている場合、システムはデータ転送を試行し続けます。ただし、データがまだ配信されていない場合、システムはデータを破棄します。アプリケーションプログラムが保留中のデータをまったく使用しない場合、ソケットを閉じる前にシャットダウンサブルーチンを使用できます。
close
とshutdown
を呼び出すと、基になるソケットに2つの異なる効果があります。
最初に指摘することは、ソケットが基盤となるOSのリソースであり、複数のプロセスが同じ基盤となるソケットのハンドルを持つことができるということです
close
を呼び出すと、ハンドルカウントが1つ減り、ハンドルカウントがゼロに達すると、ソケットと関連する接続は通常のクローズ手順を実行します(実質的にFIN/EOFをピア)、ソケットの割り当てが解除されます。
ここで注意すべきことは、別のプロセスがまだソケットへのハンドルを持っているためにハンドルカウントがゼロにならない場合、接続閉じられず、ソケットの割り当てが解除されないことです
一方、読み取りと書き込みのためにshutdown
を呼び出すと、基礎となる接続が閉じられ、ソケットへのハンドルを持つプロセスの数に関係なく、FIN/EOFがピアに送信されます。ただし、それはしないソケットの割り当てを解除するため、後でcloseを呼び出す必要があります。
シャットダウンとクローズの説明: グレースフルシャットダウン(msdn)
シャットダウン(あなたの場合)は、接続のもう一方の端に、ソケットからの読み取りまたはソケットへの書き込みを行う意図がこれ以上ないことを示します。次に、ソケットに関連付けられているメモリをすべて解放します。
シャットダウンを省略すると、接続が正常に閉じられるまで、ソケットがOSスタックに残る場合があります。
IMOの名前「shutdown」と「close」は誤解を招きやすく、「close」と「destroy」は違いを強調します。
上記のこのコードは間違っていませんか?
シャットダウン呼び出しの直後に閉じる呼び出しを行うと、カーネルはすべての発信バッファーを破棄します。
http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable one needs読み取りから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バッファーに送信されることが保証されるだけです。
Aでshutdown(1)を呼び出すことにより、Aのバッファをフラッシュし、バッファが空でない場合はエラーが発生します。つまり、データはまだピアに送信されていません
ただし、これは取り返しのつかないため、すべてのデータを完全に送信し、ピアosバッファーで少なくともそれを確認した後、それを行うことができます