【C#】ソケット通信 サーバー編(接続待ちを中断) 

スポンサーリンク

前回の記事で、ソケット通信のサーバーを作成しました。

1点課題を見つけました。

それは、クライアントから接続がないと下記行で停止してしまう事です。

tcp = listener.AcceptTcpClient();

要はクライアントからの接続がないと、次のステップにいく事ができません。

そこで今回は、その課題の解決方法をしたいと思います。

[方法1]監視スレッドを作る

1つ目の方法は、監視スレッドを作って、接続がなければ、サーバーを停止させることです。

ただこの方法をすると、強制的にサーバーを停止させるので、例外が発生します。

オススメはできないですし、強制停止させる為のロジックを考えないといけません。

では、参考に作ってみました。

bool IsStop = false;
private void Check_Listener()
{
    IsStop = false;
    for (int n = 0; n < 100; n++)
    {
        Thread.Sleep(100);
        if (IsStop == true)
        {
            //フラグが立っていたら終了
            return;
        }
    }

    //ループが回り切ったという事は、接続がなかったという事
    //リスナーを強制終了
    listener.Stop();
}

監視用の関数です。(bool型)IsStopを見て、未接続状態が続いたかを確認します。

今回は約10秒間接続がなければ、強制終了です。(100msec * 100回 = 10秒)

※Thread.Sleepを使いたい場合は、using System.Threadingを明示してください。

  

listener.AcceptTcpClient()を実行前にスレッドを作って実行しましょう。

もし次のステップに行った場合、IsStop=trueにします。

//監視スレッド実行
ThrMon = new Thread(Check_Listener);
ThrMon.Start();

try
{
     //クライアント接続待ち
     tcp = listener.AcceptTcpClient();
}
catch
{
     rcv = "";
    return -1;
}

//監視スレッド停止
IsStop = true;

スレッドから強制的にサーバーが停止させられたら、例外が発生するので、try-catchで捕まえます。

実際に動かしてみましょう。無事(?)に接続待ち状態から解放されました。

例外を発生させるのはちょっとスマートではありませんね。

[方法2]接続要求があるかを事前に確認

次にやるのは、そもそも接続待ちをする前に、接続したいクライアントがいるかを確認する方法です。

この方法の方がスマートでいいと思います。オススメな方法です。

TcpListener.Pendingメソッドを使用し、保留中の接続要求があるかどうかを確認します。

そうする事で、接続要求が無い時は、接続待ちに行かないようにします。

では、サンプルです。

if(listener.Pending() == false)
{
    Thread.Sleep(500);
    rcv = "";
    return -1;
}

tcp = listener.AcceptTcpClient();

接続要求があれば、接続待ち(listener.AcceptTcpClient())へ行きます。

接続要求がなければ、500msec待って、終了します。

関数的には終了しますが、終了後ループで回ってきますので、再度接続要求があるかを確認します。

まとめ

TCPサーバーのクライアント接続待ち(listener.AcceptTcpClient)を途中で止める方法を記載しました。

他にも方法があるかもしれません。

方法2のPendingを使う方が、接続がないのに接続待ちをする必要がなくなるので、プログラムを読む立場であればオススメな方法だと思います。

コメント

タイトルとURLをコピーしました