12

これまでのところ、私はこのコードサンプルを持っています:

...
int nbytes =0;
vector<unsigned char> buffer;
buffer.resize(5000);
nbytes = recv(socket, &buffer[0], buffer.size(),0);
//since I want to use buffer.size() to know data length in buffer I do
...
buffer.resize(nbytes);

resize()を2回使用せずに、バッファー内のデータ長を知ることは別の方法ですか?適切なサイズにサイズ変更されていないベクトルにデータを受信することはできないためです。C ++ STLのドキュメントによると、reserve()メソッドは割り当てを行わないと思います。そして別の質問:この種の技術を使用することはメモリリークに対して安全ですか?

4

5 に答える 5

5

できることはあまりありません。電話をかける前に投稿のサイズを知ることはできませんrecv

いくつかのクリーンアップ:

std::vector<unsigned char> buffer(5000);
int result = recv(socket, buffer.data(), buffer.size(), 0);
if (result != -1) {
   buffer.resize(result);
} else {
   // Handle error
}
于 2010-11-19T09:45:00.517 に答える
3

この手法は漏れがなく、非常にクリーンで望ましい方法です。を使用std::vectorすることは、C++で可変長バッファーを実装するための推奨される方法です。

すべてのデータがベクトルに収まらない場合は、問題ありません。サイズを大きくして、既に入力されている部分に続くセクションのアドレスを渡すだけです。

使用するreserve()ことはあまり良い考えではありません-それは何size()が返されるかに影響を与えないので、あなたは便利さを失い、そしておそらく利点を得ることができません。

于 2010-11-19T09:42:32.670 に答える
1

このコードは問題ありません。resizeとの違いは、によって返される値reserveを変更する(そして実際に新しいデフォルトの初期化されたオブジェクトを作成する)のに対し、変更しない(より多くのメモリを割り当てるだけです)ということです。resizesizereserve

データの処理方法に応じて、2番目を省略して、次resizeのようなループで実行できます。

for (vector<unsigned char>::iterator it = buffer.begin(); 
     it != buffer.begin() + nbytes; 
     it++) 
{
    // process each byte
}

したがって、実際に書き込まれたデータを読み取るだけで、残りは無視できます。つまり、ベクトルのサイズを設定するのは1回だけで、その後は変更しないでください。一般に、イテレータのみを使用する限り、有効なデータ範囲は常にであるため、ベクトルのサイズを変更する必要はありません[buffer.begin(), buffer.begin() + nbytes)

于 2010-11-19T09:42:13.223 に答える
1

私はそうは思わない[もっとエレガントな方法?]。recv基本的に、バッファには何バイトにも及ぶ十分な文字が必要です。次に、それらを読み取った後、受信したバイトのみをバッファに含める場合は、サイズを下方に変更する必要があります。あなたが示したことは、おそらく私が物事に取り組む方法と似ています。

あなたは正しいですが、それreserveは十分ではありません。存在せず、事前にストレージが割り当てられているだけの要素に書き込むことはできません。

于 2010-11-19T09:43:37.687 に答える
0

TCPを使用する場合は、より洗練された方法があります。メッセージヘッダーを使用します。
ヘッダーの(固定)サイズがわかっているので、これを固定サイズのバッファーで読み取ることができます。
ヘッダー内にはメッセージサイズがあるため、これを使用してバッファーを割り当て、ヘッダーで指定されているバイト数を読み取ることができます。

これを使用すると、長いメッセージの断片化などの特殊なケースにいくつかのテクニックが必要になる場合があることに注意してください。

于 2010-11-19T09:57:50.913 に答える