C#TCPサーバーアプリケーションがあります。TCPクライアントがサーバーから切断されたときに切断を検出しますが、ケーブルの接続解除イベントを検出するにはどうすればよいですか?イーサネットケーブルを抜くと、切断を検出できません。
4 に答える
「ping」機能を適用することをお勧めします。これは、TCP接続が失われると失敗します。このコードを使用して、Socketに拡張メソッドを追加します。
using System.Net.Sockets;
namespace Server.Sockets {
public static class SocketExtensions {
public static bool IsConnected(this Socket socket) {
try {
return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
} catch(SocketException) {
return false;
}
}
}
}
使用可能な接続がない場合、メソッドはfalseを返します。Reveice / SendメソッドにSocketExceptionsがない場合でも、接続があるかどうかを確認するために機能するはずです。接続の喪失に関連するエラーメッセージが表示された例外が発生した場合は、接続を確認する必要がなくなったことを覚えておいてください。
この方法は、ソケットが接続されているように見えるが、実際の場合とは異なる場合に使用することを目的としています。
使用法:
if (!socket.IsConnected()) {
/* socket is disconnected */
}
NetworkAvailabilityChangedイベントを試してください。
私はここでこの方法を見つけました。接続のさまざまな状態をチェックし、切断を通知します。ただし、接続されていないケーブルは検出されません。さらに検索と試行錯誤を繰り返した結果、これが最終的に解決した方法です。
Socket
サーバー側で受け入れられた接続からのクライアントソケットを使用し、クライアント側でサーバーに接続したクライアントを使用するパラメーターとして。
public bool IsConnected(Socket socket)
{
try
{
// this checks whether the cable is still connected
// and the partner pc is reachable
Ping p = new Ping();
if (p.Send(this.PartnerName).Status != IPStatus.Success)
{
// you could also raise an event here to inform the user
Debug.WriteLine("Cable disconnected!");
return false;
}
// if the program on the other side went down at this point
// the client or server will know after the failed ping
if (!socket.Connected)
{
return false;
}
// this part would check whether the socket is readable it reliably
// detected if the client or server on the other connection site went offline
// I used this part before I tried the Ping, now it becomes obsolete
// return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
}
catch (SocketException) { return false; }
}
この問題は、次のようにキープアライブソケットオプションを設定することでも解決できます。
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.SetKeepAliveValues(new SocketExtensions.KeepAliveValues
{
Enabled = true,
KeepAliveTimeMilliseconds = 9000,
KeepAliveIntervalMilliseconds = 1000
});
これらのオプションを調整して、接続が有効であることを確認するためにチェックを実行する頻度を設定できます。Tcpキープアライブを送信すると、ソケット自体がトリガーされ、ネットワークケーブルの切断が検出されます。