12

.NET でキープ アライブ チェックを行う方法を探しています。このシナリオは、UDP と TCP の両方を対象としています。

現在TCPで私がしていることは、片側が接続し、送信するデータがない場合、X秒ごとにキープアライブを送信することです。

反対側にデータをチェックしてもらい、X 秒以内に受信されなかった場合は、イベントなどを発生させます。

私がやろうとした1つの方法は、ブロッキング受信を行い、ソケットのRecieveTimeoutをX秒に設定することでした。しかし、問題は、タイムアウトが発生するたびに、ソケットの受信が SocketExeception をスローし、こちら側のソケットが閉じることでした。これは正しい動作ですか? タイムアウト後にソケットが閉じる/終了するのはなぜですか?

データがあり、スリープが受け入れられないかどうかのチェック (スリープ中にデータの受信が遅れている可能性があるため)。

では、これを行う最善の方法は何ですか?また、反対側で説明した方法が失敗するのはなぜですか?

4

4 に答える 4

19

文字通り「KeepAlive」を意味する場合は、次のことを試してください。

    public static void SetTcpKeepAlive(Socket socket, uint keepaliveTime, uint keepaliveInterval)
    {
        /* the native structure
        struct tcp_keepalive {
        ULONG onoff;
        ULONG keepalivetime;
        ULONG keepaliveinterval;
        };
        */

        // marshal the equivalent of the native structure into a byte array
        uint dummy = 0;
        byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
        BitConverter.GetBytes((uint)(keepaliveTime)).CopyTo(inOptionValues, 0);
        BitConverter.GetBytes((uint)keepaliveTime).CopyTo(inOptionValues, Marshal.SizeOf(dummy));
        BitConverter.GetBytes((uint)keepaliveInterval).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);

        // write SIO_VALS to Socket IOControl
        socket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);
    }

時間の単位はミリ秒であることに注意してください。

于 2008-10-05T01:52:12.827 に答える
1

MSDN によると、Receive 呼び出しで ReceiveTimeout を超えたときにスローされる SocketException は、ソケットを閉じません。コードで何か他のことが起こっています。

キャッチされた SocketException の詳細を確認してください - おそらくそれはタイムアウトではありません。接続の反対側がソケットをシャットダウンしている可能性があります。

ネットワーク トレースを有効にして問題の正確な原因を診断することを検討してください。MSDN で「ネットワーク トレース」を探してください (現在 MSDN がダウンしているため、リンクを提供できません)。

于 2008-10-04T12:59:14.807 に答える
0

ブロッキング(同期)受信は使えないので、非同期処理で我慢する必要があります。幸いなことに、これは .NET では非常に簡単に実行できます。BeginReceive() と EndReceive() の説明を探します。または、この記事またはこれをチェックしてください。

タイムアウトの動作に関しては、これに関する決定的な説明は見つかりませんでした。それ以外の場合は文書化されていないため、意図した動作であると想定する必要があります。

于 2008-10-03T22:56:05.243 に答える