前回のように同期ソケット通信にマルチスレッドを追加してノンブロッキングモードを実現するなら、最初っから非同期ソケット通信にしたらどうだろうと、試してみる事に。
マイクロソフトのドキュメントによると、
・非同期サーバーソケットは、.NET Frameworkの非同期プログラミングモデルを使用してネットワークサービス要求を処理します。Socketクラスは、標準の.NET Frameworkの非同期名前付けパターンに従います。例えば、同期のAcceptメソッドは非同期のBeginAcceptメソッドとEndAcceptメソッドに対応します。
非同期サーバーソケットには、ネットワークからの接続要求の受け入れを開始するメソッド、接続要求を処理してネットワークからデータの受信を開始するコールバックメソッド、データの受信を終了するコールバックメソッドが必要です。
・非同期クライアントソケットは、標準の.NET Framework非同期プログラミングモデルを使用して、1つのスレッドでネットワーク接続を処理しながら、アプリケーションは元のスレッドで実行を継続します。非同期メソッドの場合、Socketクラスは.NET Frameworkの名前付けパターンに従います。例えば、同期のReceiveメソッドは非同期のBeginReceiveメソッドとEndReceiveメソッドに対応します。
非同期操作には、操作の結果を返すコールバックメソッドが必要です。結果を知る必要がないアプリケーションの場合、コールバックメソッドは必要ありません。
非同期クライアントソケットには、ネットワークデバイスへの接続を開始するメソッドと接続を完了するコールバックメソッド、データの送信を開始するメソッドと送信を完了するコールバックメソッド、およびデータの受信を開始するメソッドとデータの受信を終了するコールバックメソッドが必要です。
・何れのコールバックメソッドもAsyncCallbackデリゲートを実装しており、voidを返してIAsyncResult型の1つのパラメーターを受け取ります。
らしいのですが、今一つピンと来ないのでSocket操作の表を作ってみました。
非同期サーバーソケット | 非同期クライアントソケット | ||||||||
---|---|---|---|---|---|---|---|---|---|
操作・動作 | メ *1 | サ *2 | デ *3 | 操作・動作 | メ *1 | サ *2 | デ *3 | ||
Button1_Click | ○ | Button1_Click | ○ | ||||||
. | BeginAccept が AcceptCallback 呼出し |
↑ | ○ | . | BeginConnect が ConnectCallback 呼出し |
↑ | ○ | ||
AcceptCallback | ○ | ConnectCallback | ○ | ||||||
. | EndAccept | ↑ | . | EndConnect | ↑ | ||||
. | BeginReceive が ReadCallback 呼出し |
↑ | ○ | Button1_Click | ○ | ||||
ReadCallback | ○ | . | Send 呼出し | ↑ | |||||
. | EndReceive | ↑ | Send | ↑ | |||||
. | Send 呼出し | ↑ | . | BeginSend が SendCallback 呼出し |
↑ | ○ | |||
Send (ReadCallback) | ↑ | SendCallback | ○ | ||||||
. | BeginSend が SendCallback 呼出し |
↑ | ○ | . | EndSend | ↑ | |||
SendCallback | ○ | Button1_Click | ○ | ||||||
. | EndSend | ↑ | . | Receive 呼出し | ↑ | ||||
Receive | ↑ | ||||||||
. | BeginReceive が ReceiveCallback 呼出し |
↑ | ○ | ||||||
ReceiveCallback | ○ | ||||||||
. | EndReceive | ↑ | |||||||
. | (BeginReceive が ReceiveCallback 呼出し) |
(↑) | (○) |
*1:メインスレッド
*2:サブスレッド
*3:AsyncCallbackのデリゲート実装を示す
でも、却って分かり辛くなってしまった感じも?
あと、非同期にすると例外処理がどう変わるのかも、今一不明(ちゃんと調べろよ!)。
<注意点>
・動作は非同期なので、ノンブロッキングモードらしいです。