Linuxに関するこの質問を読みました。プロセスが終了したときにポートをバインドできますか?
Linuxは、プロセスが終了し、開いているソケットを残した後にクリーンアップするようです。これがWindowsでどのように機能するかについての仕様があるかどうか疑問に思っていました。OSは、終了せずに終了するプロセスのソケットを常に閉じますか?
Linuxに関するこの質問を読みました。プロセスが終了したときにポートをバインドできますか?
Linuxは、プロセスが終了し、開いているソケットを残した後にクリーンアップするようです。これがWindowsでどのように機能するかについての仕様があるかどうか疑問に思っていました。OSは、終了せずに終了するプロセスのソケットを常に閉じますか?
回答:
WindowsとUnixenの両方で、プロセスが終了すると、カーネルは開いているすべてのハンドルを閉じます。
プロセスの終了 -MSDN
プロセスを終了すると、次の結果が得られます。
- [...]
- プロセスによって割り当てられたリソースはすべて解放されます。
- すべてのカーネルオブジェクトが閉じられます。
- [...]
プロセスが終了すると、カーネルオブジェクトへの開いているハンドルは自動的に閉じられますが、オブジェクトに対するすべての開いているハンドルが閉じられるまで、オブジェクト自体は存在します。したがって、オブジェクトは、別のプロセスが開いているハンドルを持っている場合、それを使用しているプロセスが終了した後も有効なままです。
ExitProcess
関数 – MSDNプロセスを終了すると、次のことが起こります。
- [...]
- プロセスによって開かれたすべてのオブジェクトハンドルが閉じられます。
- [...]
exit(3)
– Linuxプログラマーズマニュアル(libc関数)開いているすべてのstdio(3)ストリームはフラッシュされ、閉じられます。
_exit(2)
– Linuxプログラマーズマニュアル(カーネルsyscalls)この関数
_exit()
は、呼び出しプロセスを「即座に」終了します。プロセスに属する開いているファイル記述子はすべて閉じられます。プロセスのすべての子はプロセス1、initに継承され、プロセスの親にはSIGCHLDシグナルが送信されます。
両方のオペレーティングシステムで、
ソケットはファイル記述子(fd)/カーネルオブジェクトの1つのタイプにすぎないため、上記はファイルとソケットに等しく適用されます。
ファイルのUnix上の説明だけでなく、オブジェクトハンドル Windows上のカーネルオブジェクトは、が所有することができ、複数のプロセス- 彼ら彼らのハンドルが子プロセスによって継承され、さらには特別なIPC機能を使用して周りに渡すことができます。
ファイルまたはソケットは、それを指しているすべての fdが破棄されたときにのみ閉じられます。
Windowsでは、ソケットは通信エンドポイントとプロセス間のリンクです。これが、ソケットを複製するときに、2つのソケットが1つのエンドポイントだけで終わる理由です。これが、他のプロセスで新しいソケットを作成せずに、あるプロセスから別のプロセスにソケットを渡すことができない理由です。
プロセスが存在しなくなると、そのソケットは必ず存在しなくなります。ソケットを保持するプロセスがないソケットの概念はありません。そのため、カーネルレベルでソケットを作成するWindowsカーネルドライバーでさえ、ソケットを所有するプロセスを指定するか、ソケットを所有できるプロセスコンテキストから関数を呼び出す必要があります。(または、ソケットを使用せずにエンドポイントを直接操作できます。)
あなたの質問は、実際にはソケットに関するものではなく、通信エンドポイント自体に関するもののようです。ソケットには、通信エンドポイントへの参照があります。ソケットがなくなると、参照カウントは低下します。ゼロに達した場合、エンドポイントが関連付けられている通信プロトコルの要件を考慮すると、許容されるとすぐに削除されます。TCPにはTIME_WAIT状態があり、その間、「残り」のパケットを処理するためにエンドポイントを維持する必要があります。
はい、そうです。このようにして、Windows 3.1 95 98 XP(少なくともXP以降は確実にわかります)を検出しました。
WSACleanup()
そうしないとリークが発生しました。また、DOS-Windows 9xには厄介な問題があり、MSKB記事#156319に文書化されています。親プロセスは、DOS-Windowsのソケットの異なるプロセス終了セマンティクスによって、子プロセスに渡されるソケットを無効にします。