[解決済み] boost::asio::buffer。バッファサイズを取得し、バッファオーバーフローを防ぐ?
質問内容
パケットを送受信するための以下の2つの関数があります。
void send(std::string protocol)
{
char *request=new char[protocol.size()+1];
request[protocol.size()] = 0;
memcpy(request,protocol.c_str(),protocol.size());
request_length = std::strlen(request);
boost::asio::write(s, boost::asio::buffer(request, request_length));
}
void receive()
{
char reply[max_length];
size_t reply_length = boost::asio::read(s, boost::asio::buffer(reply, request_length));
std::cout << "Reply is: ";
std::cout.write(reply, reply_length);
std::cout << "\n";
}
質問はこの部分に関するものです
boost::asio::buffer(reply, request_length)
ここで、リクエストの長さはパケット送信時に初期設定された文字列の長さです。を知らずにバッファのサイズを確認するにはどうしたらいいでしょうか?
request_length
? また、バッファオーバーフローを防ぐにはどうしたらよいでしょうか?
解決方法は?
バッファのサイズを取得するために
boost::asio::buffer_size()
関数が使用できます。 しかし、あなたの例では、これはほとんど役に立たないでしょう。
バッファーで説明したように
概要
Boost.Asioはバッファを表現するためにバッファクラスを使用します。 これらのクラスは抽象化を提供し、バッファオーバーランからBoost.Asioの操作を保護します。 の結果は
boost::asio::buffer()
は操作に渡されますが、バッファのサイズやその基礎となる型などのメタデータは送信されません。 また、これらのバッファはメモリを所有しないので、バッファ抽象化の有効期間中、基礎となるメモリが有効であることを保証するのは、アプリケーションの責任です。
その
boost::asio::buffer()
関数はバッファクラスを作成する便利な方法を提供し、バッファのサイズは可能な型から推論されます。 Boost.Asioがバッファの長さを推測できる場合、Boost.Asioの操作は結果のバッファタイプを使用してもバッファのオーバーフローを呼び出すことはありません。 しかし、アプリケーション・コードでバッファの大きさを
boost::asio::buffer()
その場合、そのサイズが基礎となるメモリより大きくないことを確認するのは、アプリケーションの責任です。
データを読み込む際には、バッファが必要です。 Boost.Asioがサイズを送信しない場合、どれくらいのメモリを確保すればよいのか、どうやって知ることができるのか、という根本的な疑問があります。 この問題に対しては、いくつかの解決策があります。
-
ソケットに、どれだけのデータが利用可能かを問い合わせるには
socket::available()
で、それに応じてバッファを確保します。std::vector<char> data(socket_.available()); boost::asio::read(socket_, boost::asio::buffer(data));
-
Boost.Asioがメモリ内で成長できるクラス、例えば以下のようなものを使用します。
boost::asio::streambuf
. などの一部の操作はboost::asio::read()
受け入れるstreambuf
オブジェクトをバッファとして使用し、操作に必要な分だけメモリを確保します。 しかし、完了条件を与えなければならない。さもなければ、操作はバッファが一杯になるまで続けられる。boost::asio::streambuf data; boost::asio::read(socket_, data, boost::asio::transfer_at_least(socket_.available()));
-
として Öö Tiib は、通信プロトコルの一部として長さを組み込むことを提案しています。 Boost.Asioを確認する 例 は、通信プロトコルの例です。 必ずしもBoost.Asioにこだわらず、プロトコルに着目してください。 API .
- 固定サイズプロトコルでは、データ生産者と消費者の両方が同じサイズのメッセージを使用します。 読み手はメッセージのサイズを知っているので、あらかじめバッファを確保することができる。
-
可変長プロトコルでは、メッセージはヘッダとボディの2つの部分に分けられることが多い。 ヘッダは通常固定サイズで、ボディの長さなど様々なメタ情報を含むことができる。 これにより、リーダーはヘッダを固定サイズのバッファに読み込んで、ボディの長さを抽出し、ボディ用のバッファを割り当て、それからボディを読み込むことができる。
// Read fixed header. std::vector<char> data(fixed_header_size); boost::asio::read(socket_, boost::asio::buffer(data)); protocol::header header(data); network_to_local(header); // Handle endianess. // Read body. data.resize(header.body_length()); boost::asio::read(socket_, boost::asio::buffer(data)); protocol::body body(data); network_to_local(body); // Handle endianess.
関連
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み] コピーアンドスワップ慣用句とは?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された
-
[解決済み】c++で.txtファイルから2次元の配列に読み込む