LoginSignup
30
28

More than 3 years have passed since last update.

【C#】TCP/IPサーバで通信の切断を検出する

Posted at

TCP/IPサーバでクライアントと通信している時、クライアントとの接続が切れた場合の処理のまとめです。
接続が切れたとは、以下の場合です。

  • クライアントが回線を切った
  • クライアントが強制終了した
  • ケーブルが外れるなど通信経路が切れた

クライアントが接続を切った

クライアントがshutdownを実行して回線を切った場合、サーバーのNetworkStream.Read()は長さ0の通信を受け取って終了します。

normal_end
    int readsize = stream.Read( buf, 0, buf.Length );
    if( readsize == 0 )
    {
        // クライアントが切断したときの処理
    }

クライアントが強制終了した

クライアントがWSACleanupを実行たり、ExitProcessして回線を切った場合、サーバーのNetworkStream.Read()は例外を投げて終了します。

forced_end
    try
    {
        int readsize = stream.Read( buf, 0, buf.Length );
        // クライアントからの受信処理
    }
    catch( Exception e )
    {
        // クライアントが切断したときの処理
    }

ケーブルが外れるなど通信経路が切れた

通常は無反応です。
Keep-aliveの設定を行っておくと設定条件となった時、強制終了したときと同様にNetworkStream.Read()は例外を投げて終了します。

keep-aliveとは、接続している相手に定期的にプローブという通信を投げ応答があるかどうかを確認するもので、応答がなくなったら回線に異常が生じたと検出する手法です。
プローブのON/OFF、クライアントとの通信がなくなってからプローブを送信するまでの待ち時間、プローブを送信する間隔を設定します。

keep-alive_setting
    var clientSocket = listenerSocket.Accept();
    // keep-aliveをenableに設定
    clientSocket.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true );

    // keep-aliveのパラメータ Cで言うところの、unsigned int が3つです。
    byte[] tcp_keepalive = new byte[12];
    BitConverter.GetBytes( (Int32)1 ).CopyTo( tcp_keepalive, 0 );//onoffスイッチ.
    BitConverter.GetBytes( (Int32)2000 ).CopyTo( tcp_keepalive, 4 );//wait time.(ms)
    BitConverter.GetBytes( (Int32)1000 ).CopyTo( tcp_keepalive, 8 );//interval.(ms)
    // keep-aliveのパラメータ設定
    clientSocket.IOControl( IOControlCode.KeepAliveValues, tcp_keepalive, null );

待ち時間と間隔はミリ秒で設定します。
この例では、スイッチはON、待ち時間2秒、間隔1秒、です。Windowsでは10回連続でプローブの応答がなかったら例外を発生するようです。

:exclamation:プローブはネットワークトラフィックを増やします。その点は注意。

参考URL
https://www.codeproject.com/Articles/117557/Set-Keep-Alive-Values

30
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
28