前回の記事で、ソケット通信のサーバーを作成しました。
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を使う方が、接続がないのに接続待ちをする必要がなくなるので、プログラムを読む立場であればオススメな方法だと思います。
業務でプログラミング(C#/VB/Python)を作っている。
挫折を何回も繰り返し、幾度の壁を乗り越えてきた。
乗り越えてきた事を忘れないように記録に残す。
同じ思いをしている人への情報提供になれたらと思う。
基本は初心者に向けたプログラムの情報を提供する。
コメント