1

良い一日を!

私はクローズド ソースのゲームのオープン ソース サーバーに取り組んでいます - ゲームは TCP/IP ソケットを使用して動作します (UDP の代わりに、doh...)。

私の現在のプログラム構造(ダムダウン):

コアスレッド

  • 新しい接続を受け取り、新しいクライアント オブジェクトを作成します。

クライアント オブジェクト

  • IOloop (独自のスレッドで実行)

    • ソケットからデータを取得し、パケットを処理します。(一度に 1 パケット)
    • 他のスレッドからバッファリングされたデータを送信 (一度に 1 パケット)

クライアントが独自のスレッドである場合、クライアントはすぐに (遅延なしで) データを送信します。


プログラムに大きな欠陥があることに気付きました。主に、データの送信が非常に遅いです。同期的に、パケットごとにデータを送信するためです。(Socket.Send(byte[] バッファ))

データを遅滞なく、非同期で、すぐに送信したいと考えています。

パケットを送信するたびに新しいスレッドを作成しようとしました (そのため、各パケットは独自のマネージド スレッドで送信されます) が、これは非常に面倒でした。

私の現在のシステムは、nagle アルゴリズムを無効にした同期送信を使用していますが、これにはボトルネックの欠陥があります。1 つのパケットを送信し、TCP が確認するまで操作ブロックを送信してから、次のパケットを送信します... 100 ミリ秒ごとに 10 パケットを簡単に発行できます。パケットの送信には 400 ミリ秒かかり、これがバックアップして壊れます。もちろん、ローカル ホストではこの問題は発生しません。


それで、私の質問: データの複数の小さなパケットを送信する最良の方法は何でしょうか? 前後の遅延を減らすために、すべての IO スレッド ループの最後に送信するデータを 1 つの大きなバイト バッファーにマージすることを考えています。遅れます。

同期送信はどのように機能しますか? 私が信じているように、データが受信者によって正しく受信されたことを確認するまでブロックしますか? 確認を待たずにこれを行う方法はありますか? パケットはすべて順番どおりに正しく送信する必要があることは理解しています (プロトコル仕様に従って)。

4

1 に答える 1

0

私はいくつかの調査を行い、現在は現在のシステムを使用しています。

AsyncCallbacks を使用した、スレッド化のない非同期送受信操作。

したがって、サーバーに読み取り操作を開始させ、完了するまでコールバックし、パケットが受信されると処理され、新しい読み取り操作が開始されます...

この方法により、システムのオーバーヘッド (スレッド プール、メモリなど) が大幅に削減されます。

次のいくつかの方法を使用し、好みに合わせてカスタマイズしました: https://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx

非常に効率的で、このアプローチを強くお勧めします。どの TCP/IP ネットワーク アプリケーションでも、低ラグは非常に重要であり、非同期コールバックはそれを行うための最良の方法です。

于 2016-07-08T03:49:15.857 に答える