今日も今日とて.NET。.NETで非同期ソケット通信 (←このリンクが切れていた場合、".NET", "ソケット", "非同期"などで検索すれば出てくるでしょう)する場合、データを受信するたびにSystem.Net.Sockets.Socket.BeginReceiveで指定した関数・メソッドが呼ばれます。接続が切れるときにもこの関数が呼ばれますが、その場合受信サイズが0になっているので、切断を知ることができるという仕掛けです。
相手から切断してきたときはSystem.Net.Sockets.Socket.Close()なりインスタンスの破棄なり処理すればいいのですが、こちらから切断したいときはSystem.Net.Sockets.Socket.Disconnect()で切断する必要があるようです。以下の方法では不具合がありました。
- System.Net.Sockets.Socket.Socketインスタンスの破棄
- 破棄のタイミングはプログラマーが制御できない ようなのでいつ切断されるか分かりません。下手すると延々と接続されています。
- System.Net.Sockets.Socket.Socket.Close()
- このメソッドは切断後全てのリソースを開放してしまいます 。この後サイズ0の受信を通知しようとBeginReceiveで指定した関数が呼ばれますが、引数のIAsyncResultクラスインスタンスがCloseメソッドで開放されてしまっているため、EndReceiveでこのインスタンスにアクセスするとエラーを起こします。try〜catchで例外処理など対策が必要。
ただSystem.Net.Sockets.Socket.Socket.Disconnect()メソッドは.NET Framework 2.0以降らしいので、1.xではEndReceiveをtry〜catchで捕まえるか、独自にフラグ管理するなどするしかないのでしょうか?
Comments