ここにいる他の多くの人たちと同じように、ネットワーク ライブラリを作成しようとしています。要件は基本的に次のようになります。
- 非同期で動作し、リアルタイム アプリケーションの準備を整える (私は FPS ゲームを念頭に置いています)
- UDP を使用し、必要に応じてその上に薄いプロトコル レイヤーをセットアップします
- IPv6 でネイティブに動作する
- 複数のプラットフォームをサポートします (参照: Mono サポートが必要です!)
これを行う方法について読んだ後 (最も刺激を受けたのはGaffer on Gamesでした)、開発環境をセットアップし、その方法について考え、次の基本的なワークフローを思いつきました。
- ソケットを初期化し、「UDPv6」を使用するように指示します
- そのソケットをポートにバインドし、例外をユーザーに迷惑をかけないようにします。ソケットが正しく設定されていることを彼に伝える「バウンド」プロパティがあります。
- ローカル マシンの NIC がサポートする最大 MTU について調べます。
- いくつかの SocketAsyncEventArgs を初期化し、その Completed イベントにプライベート ディスパッチ メソッドを呼び出すように指示し、そのバッファーを手順 3 の最大 MTU のサイズに設定します。
- 最初の SAEA オブジェクトを使用して Sockets ReceiveFromAsync メソッドを呼び出します。
データが入ってきたら、次のことを行います。
- 次の空いている SAEA オブジェクトを使用して ReceiveFromAsync メソッドを呼び出す
- 現在の SAEA オブジェクトからバッファと送信者の情報を取得し、再び使用できるようにします
- 受信したメッセージで新しいイベントを発生させます。
このアプローチでいくつかのテストを行いましたが、非常にうまく機能しています。10000 サイクルで 200 バイトのデータを含むメッセージを 10 ミリ秒ごとに送信しましたが、CPU やメモリの負荷はほとんど増加しませんでした。NIC の負荷のみが増加しています。しかし、私はいくつかの問題を思いついた | 質問:
- (ソケットを保持している) PeerSocket クラスを破棄すると、すべての SAEA オブジェクトが破棄されます。しかし、そのうちの少なくとも 1 つはまだ新しいメッセージをリッスンしているため、ObjectDisposedException がスローされます。聞くのをやめるように伝える方法はありますか?
- MTU は他のピアへの途中で異なる場合があります。おそらく、各 SAEA オブジェクトのバッファーは、バッファー サイズを決定するために異なるインジケーターを使用する必要がありますか?
- 断片化されたデータグラムを処理する方法がまだわかりません。送信するデータグラムにその「信頼性ヘッダー」を書き込んでいきますが、データグラムが分割されている場合、このヘッダー情報についてはわかりませんよね?
このライブラリは、いつか誰かの役に立ち、リポジトリが公開されることを願っています。この質問の時点で、現在のコミットはここにあります