3

ストックデータを受信し、ソケットを介して別のアプリケーションに転送する C++ アプリケーションがあります (サーバーとして機能します)。

実際には、WSASend関数は数秒後にエラーコード 10055 で戻り、それがエラーメッセージであることがわかりました

「利用可能なバッファスペースがありません。システムに十分なバッファスペースがないか、キューがいっぱいだったため、ソケットでの操作を実行できませんでした」。

問題が発生するのは、数分で 1 日分のデータ (約 130 MB) を受信して​​いるため (これは比較的大きいと思います)、市場時間後にアプリケーションを実行した場合にのみ発生します (これは比較的大きいと思います)。これは堅牢性テストとして行っています。

関数を使用して送信バッファ SO_SNDBUF を増やそうとしましたsetsockoptが、同じ問題がまだ残っています。どうすればこの問題を解決できますか? これは受信バッファに関連していますか?

送信の詳細:

完全なメッセージごとに、重複したソケットを使用する send メソッドを呼び出します

編集:誰かがC++で高周波データを処理するための一般的なガイドラインを与えることができますか?

4

2 に答える 2

6

TCP のフロー制御により、受信者がソケットの終了を十分に速く処理していない場合、内部送信バッファがいっぱいになります。エラー メッセージから、Winsock スタックの処理速度に関係なくデータを送信しているように見えます。データの送信方法を正確に記載していただければ助かります。すべてのデータが到着するのを待ってから、1 つの大きなブロックを送信しますか、それとも少しずつ送信しますか?

ノンブロッキングまたはオーバーラップ ソケット経由で送信していますか? いずれの場合も、送信のたびに、select()/WaitForMultipleObjects() が (ノンブロッキング ソケットの場合) 送信できることを示しているため、ソケットがより多くのデータを送信できる状態にあるという通知を待つ必要があります。オーバーラップした I/O が完了し、データがソケットの内部送信バッファーに正常にコピーされたことを通知します。

送信をオーバーラップできます。つまり、一度に複数のバッファーをキューに入れることができます。これがオーバーラップ I/O の目的です。 .

于 2009-02-28T09:44:21.193 に答える
0

ニックの答えはほとんど頭の爪に当たる。一度に多くの重複した送信を開始することにより、「ロックされたページの制限」を使い果たしている可能性があります。理想的には、データを独自のメモリバッファにバッファリングし、一度に保留になっている重複した送信の数を設定するだけにする必要があります。私のIOCPフレームワークでこの種の状況に対処する方法については、http://www.lenholgate.com/blog/2008/07/write-completion-flow-control.htmlおよび関連するTCP受信ウィンドウフロー制御について説明します。ここで問題http://www.lenholgate.com/blog/2008/06/data-distribution-servers.htmlそしてここhttp://www.serverframework.com/asynchronousevents/2011/06/tcp-flow-control-and -asynchronous-writes.html

私の推奨する解決策は、一度に構成可能な数の保留中のオーバーラップ送信を許可し、この制限を超えると、データのバッファリングを開始し、保留中のオーバーラップ送信の完了を使用して、バッファリングされたデータの送信を駆動することです。これにより、非ページプールの量と使用される「ロックされたページ」の量を厳密に制御でき、多くの接続を可能な限り高速に送信しながら、使用するリソースを制御することができます。

于 2009-03-09T21:18:57.080 に答える