2012-02-17 1 views
1

問題:My Completionport Serverは、さまざまなクライアントから不明なサイズのデータ​​を受け取ります。問題は、バッファオーバーランを回避する方法がわかりません/バッファにデータがオーバーフィルされないようにする方法です。WSARecv、Completionportモデル、バッファを管理してオーバーランを回避する方法は?

Quesitons: 1)私がWSARecv経由で受信呼び出しを行う場合、workerthreadはコールバック関数のように機能しますか?つまり、受信コールが完了したときにのみ受信コールを掘り起こすのですか、受信が起きたときに受信コールを掘り起こすのでしょうか? lpNumberOfBytes(GetQueuedCompletionStatusから)変数に、現在までに受信したバイト数または受信したバイト数の合計が含まれていますか?

2)オーバーランを回避するには、動的に割り当てられたバッファ構造を考えましたが、再度、どのくらいの大きさのパッケージが得られるのかを確認するにはどうすればよいですか?

編集:私はこれを尋ねるのは嫌ですが、バッファを管理してオーバーランを避けるための「単純な」方法はありますか?同期は少なくとも私に今までに限界を呼んでいる

答えて

1

WSARecv経由で受信呼び出しを行う場合、workerthreadはコールバック関数のように機能しますか?

@valdo投稿を参照してください。スレッドのプールにキューイングされた完了データは、処理される準備が整います。

「受信コールが完了したときに受信コールを掘り下げますか?」はい - したがって名前。 「完了」の意味は異なる場合があります。プロトコルによって異なります。 TCPでは、ピアからいくつかのストリーミングされたデータバイトが受信されたことを意味します。

'(GetQueuedCompletionStatusからの)変数lpNumberOfBytesには今までに受信したバイト数または受信したバイト数の合計が含まれていますか? IOCP補完でのみ提供されたバッファ配列に受信されてロードされたバイト数が格納されます。

'オーバーランを避けるには、動的に割り当てられたバッファ構造を考えていましたが、もう一度、パッケージの大きさを知るにはどうすればよいでしょうか?バッファ配列を提供すると、オーバーランを得ることはできません。バッファをロードするカーネルスレッドは、渡されたバッファ長を超えません。アプリケーションレベルでは、TCPのストリーミング性を考慮して、バッファ配列を使用可能なアプリケーションレベルのプロトコル単位に処理する方法を決定する必要があります。適切なバッファ管理スキームについて、提供されているサービスに関する知識を使用して決定する必要があります。

最後のIOCPサーバは、まったく汎用性がありませんでした。私はバッファプールの配列と起動時に(ソケットオブジェクトのプールと共に)割り当てられた 'buffer-carrier'オブジェクトのプールを使用しました。各バッファプールは、異なるサイズのバッファを保持していました。新しい接続時に、最小のプールから1つのバッファを使用してWSARecvを発行しました。このバッファがいっぱいになったら、次のWSARecvのために次に大きいプールからバッファを使いました。

次に、複数のハンドラスレッドで順序外バッファリングを防止するために必要なシーケンス番号の問題があります。(

1

_1。完了ポートは、キュー(I/O完了をキューからデキューするのを待っているスレッドの優先順位に関する洗練されたロジック)の並べ替えです。 I/Oが完了すると(成功または失敗)、完了ポートにキューイングされます。次に、GetQueuedCompletionStatusというスレッドの1つによってデキューされます。

"進行中"のI/Oをデキューしないようにします。さらに、ワーカースレッドによって非同期に処理されます。つまり、スレッドがGetQueuedCompletionStatusを呼び出すまで延期されます。

_2。これは実際には複雑な問題です。同期は全体的には些細な作業ではありません。特に対称マルチスレッド(複数のスレッドがある場合はそれぞれがすべてを実行している可能性があります)に関しては特にそうです。

完了したI/Oで受け取るパラメータの1つは、OVERLAPPED構造体(これはWSARecvなどのI/Oを発行した関数に指定したもの)へのポインタです。 OVERLAPPEDに基づいて(それを継承するか、それを最初のメンバーとして持つ)独自の構造体を割り当てるのが一般的です。完了を受け取ると、デキューされたOVERLAPPEDを実際のデータ構造にキャストすることができます。

しかし、カスタムを持っていても(パフォーマンスを良くし、デッドロックを回避するために)正しく同期させるのは簡単なことではありません。コンテキスト。これには正確な設計が必要です。

関連する問題