接続が確立されたあと、どのピアもデータを送信しなければ、ネットワーク上にパケットは流れません。TCP はアイドルプロトコルであるため、接続はアクティブだとみなされます。
切断の原因- アプリケーションのクローズ: プロセスが終了する際は通常、接続が閉じられたことを相手ピアに通知する FIN パケットを送信します。しかしプロセスがクラッシュした場合、このパケットが相手ピアに送信される保証はありません。
- デバイスのクローズ: デバイスがクローズされた場合、それに関する通知はほぼ得られません。
- ネットワークケーブルの抜線: ネットワークケーブルが抜かれた状態はルーターがクローズしたのと同じで、データが転送されないため接続はクローズされません。
- ルーターからの信号喪失: アプリケーションがルーターからの信号を失っても、接続はアクティブのままです。
ハーフオープン切断の検出
切断は次の方法で検出を試みることができます。
2 つ目の接続
2 つ目の接続を開いてみる方法がありますが、リソースを多く消費したり、新しいスレッドを生成したりするデメリットがあります。また、相手ピアが再起動した場合、2 つ目の接続は成功しても 1 つ目は失敗します。
相手ピアへの Pingハーフオープン接続に対して Ping やその他のメッセージを送信しても、エラーは返ってきません。
TCP ソケットレベルで KeepAlive を有効化するTCP キープアライブパケットとは、シーケンス番号がその接続の現在のシーケンス番号より 1 つ少ない ACK にすぎません。これらの ACK を受信したホストは、現在のシーケンス番号で ACK を返します。キープアライブは、接続のリモート側にあるコンピューターがまだ利用可能かどうかを確認するために使用できます。TCP キープアライブは、TCP 接続上で他のデータや上位レベルのキープアライブが送信されていない場合、TCPKeepAlive.Time(デフォルトは 7,200,000 ミリ秒 = 2 時間)ごとに 1 回送信できます。キープアライブに応答がない場合は、TCPKeepAlive.Interval 秒ごとに繰り返されます。KeepAliveInterval のデフォルトは 1000 ミリ秒です。
接続ごとに KeepAlive を有効化し、TCP プロトコルに接続がアクティブかどうかを確認させることができます。ネットワークケーブルが抜かれた場合のような切断を検出したい場合、これが推奨される方法です。sgcWebSockets 4.3.7 から TCPKeepAlive プロパティを有効にして、ハーフオープン接続の検出を試みることができます。
oClient := TsgcWebSocketClient.Create(nil); oClient.TCPKeepAlive.Enabled := True; oClient.TCPKeepAlive.Time := 3000; oClient.TCPKeepAlive.Interval := 1000;
