プローブの数またはプローブ間隔を変更するには、次のように /proc ファイルシステムに値を書き込みます
echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl
echo 20 > /proc/sys/net/ipv4/tcp_keepalive_probes
これらの値は、システム上でキープアライブが有効になっているすべてのソケットに対してグローバルであることに注意してください。setsockopt を設定すると、ソケットごとにこれらの設定を上書きすることもできます。リンクしたドキュメントのセクション 4.2 を参照してください。
キープアライブを使用してユーザー空間からソケットのステータスを「チェック」することはできません。代わりに、カーネルは、リモート エンドにパケットの確認を強制し、ソケットが不良になっているかどうかを判断することについて、より積極的です。ソケットに書き込もうとすると、キープアライブがリモート エンドがダウンしていると判断した場合、SIGPIPE が返されます。
SO_KEEPALIVE を有効にすると、SO_KEEPALIVE を有効にしない場合と同じ結果が得られます。通常、ソケットの準備ができており、そこから読み取るとエラーが発生します。
Linux では、キープアライブ タイムアウトをソケットごとに設定できます (これは Linux 固有の機能である可能性があります)。システム全体の設定を変更するよりも、これをお勧めします。詳細については、tcp の man ページを参照してください。
最後に、クライアントが Web ブラウザの場合、いずれにせよかなり迅速にソケットを閉じる可能性が非常に高くなります。それらのほとんどは、キープアライブ (HTTP 1.1) 接続を比較的短い時間 (30 秒、1 分など) だけ開いたままにします。もちろん、クライアント マシンが消えたり、ネットワークがダウンしたりした場合 (これは SO_KEEPALIVE が検出に非常に役立ちます)、積極的にソケットを閉じることはできません。
すでに説明したように、SO_KEEPALIVE は、何もしていないときでも継続的に接続を検証するようにカーネルをより積極的にしますが、そうではありません 情報の配信方法を変更または強化する。実際に何かをしようとすると (たとえば「書き込み」)、カーネルが以前に設定されたフラグのステータスを報告するだけなので、すぐにわかります。しばらく待つ必要はありません。ネットワーク アクティビティが失敗するまで数秒 (場合によってはそれ以上) かかります。 「反対側が予期せず離れてしまった」状態を処理するために使用したのとまったく同じコード ロジックが引き続き使用されます。変更されるのはタイミングです(方法ではありません)。
実質的にすべての「実用的な」ソケット プログラムは、何らかの方法で non を提供します。 -データフェーズ中のソケットへのアクセスのブロック (select()/poll() を使用するか、fcntl()/O_NONBLOCK/EINPROGRESS&EWOULDBLOCK を使用するか、カーネルがサポートしている場合は MSG_DONTWAIT を使用する可能性があります)。これが他の理由で既に行われていると仮定すると、さらに接続の切断についてすぐに調べるのは簡単です (コードがまったく必要ない場合もあります)。しかし、データ フェーズがそうでない場合 何らかの方法でソケットへの非ブロッキング アクセスを既に提供している場合は、次に何かをしようとするまで、接続が切断されたことに気付くことはありません。
(データ フェーズ中に何らかのノンブロッキング動作を行わない TCP ソケット接続は、壊れやすいことで有名です。たとえば、間違ったパケットがネットワークの問題に遭遇した場合、プログラムが無期限に「ハング」するのは非常に簡単です。できます。)