いつもお世話になっております。.NET Framework 4.5.2で動かす TCP 通信プログラム(NTサービスアプリケーション)を作成しています。
###前提・実現したいこと
TCP接続を非同期で受けつけて通信処理を行うプログラムで、アプリケーション終了時には、接続受付を終了させます。
###発生している問題・エラーメッセージ
System.Net.Sockets.TcpListener.BeginAcceptSocket メソッドで非同期接続待ちを開始した場合は、System.Net.Sockets.TcpListener.EndAcceptSocketメソッドで終わらせる必要があるそうです。
接続要求があった場合に呼び出されるハンドラで Accept させる場合には EndAcceptSocket メソッドを呼び出すときは、その引数にハンドラで受け取った IAsyncResult インターフェイスの仮引数を指定すれば、Acceptされて通信用の TcpClient オブジェクトが得られます。が、単に接続待ち自体を終了させたい場合は、EndAcceptSocket メソッドの引数に何を指定すればよいのでしょうか?
ちなみに、TcpListener(のオブジェクト)を Stop メソッドで停止させると、BeginAcceptSocket メソッドで指定したハンドラが呼び出されますが、ここで EndAcceptTcpClient メソッドを呼び出すと、 ObjectDisposedException が発生してしまいます。
ObjectDisposedException を捕捉すれは異常終了は避けられますが、このような止め方でも問題はないのでしょうか?通常処理を例外捕捉で終了させることはなんだか気持ち悪いです。例外処理はあくまで例外と考えると本来の Graceful な方法がほかにあるような気がしますが、ご存知の方がいらっしゃいましたらご教示いただけますと幸いです。
###該当のソースコード
c#
1 public partial class MyServiceApp : ServiceBase 2 { 3 private System.Net.Sockets.TcpListener _listener; 4 5 //...関係なさそうなコードは略しています 6 7 protected override void OnStart(string[] args) 8 { 9 _listener = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 10000); // 10000 は試験用 10 _listener.Start(); 11 _listener.BeginAcceptTcpClient(OnAccepting, null); 12 } 13 14 protected override void OnStop() 15 { 16 // _listener.EndAcceptTcpClient(null); // <- これではArgumentNullException 17 _listener.Stop(); 18 } 19 20 private void OnAccepting(IAsyncResult ar) 21 { 22 //try 23 var socClient = _listener.EndAcceptTcpClient(ar); // <- ObjectDisposedException が発生 24 25 _listener.BeginAcceptTcpClient(OnAccepting, null); 26 27 //catch... 28 } 29 }
###補足情報(言語/FW/ツール等のバージョンなど)
- Visual Studio 2013 Professional、C# で開発しています。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/09/05 00:03 編集