1

Qt 以外の別のプログラムによって作成された定義済み構造のストリーミング バイナリ データ (QDataStream) を処理する必要があります。そのデータを解釈するためのベストプラクティスは何だろうか。データがテレグラムで次のように構造化されており (構造体定義が提供されている)、自分で変更できないとします。

4 バイトのヘッダー | 2 バイトのシーケンス番号 | 1 バイトのチェックサム | 10バイトデータ

「Telegram」クラスでデータを処理するには、次の可能性があります。

  1. Telegram クラスには、プライベート QByteArray メンバー変数があります。すべてのデータ (17 バイト) は、readRawData メソッドを使用してストリームから一度に読み取られ、そこに格納されます。変数はreturn (array.at(4)<<8) + array.at(5)、シーケンス番号のような public メソッドでアクセスおよび解釈されますが、あまり洗練されていません。
  2. Telegram クラスには、構造体と結合した public char[17] メンバー変数があります。すべてのデータは、readRawData を使用してストリームから読み取られ、そこに格納されます。後で変数にアクセスするとき、これは構造体に対してのみ行われtelegramstruct.squenceNumberます。エンディアンやパディングなど、このメソッドには潜在的な問題があることがわかります。
  3. Telegram クラスには、 のような電報フィールドごとにプライベート メンバー変数がありますQString strHeader。ストリームからテレグラムを読み取るとき、データはこれらの変数に直接保存されます。読み取りは readRawData または基本型の operator>> を使用して行われます。

処理するデータが多いため、コードはできるだけ高速にする必要があります。MinGW を使用して Windows で Qt 5.0.1 を使用しています。

私の質問:

  • 上記の解決策のうち、ベスト プラクティスで高速なのはどれですか。それとも、より良い方法がありますか?
  • 1 のように一度にすべてを読み取るのは、3 のように 4 バイト、2 バイト、1 バイトなどを読み取るよりも高速ですか?
  • 1 と 3 では、定義済みの構造体で提供されたヘッダー ファイルを使用できません。それは悪い習慣でしょうか?
  • QByteArray と構造体との一種の「ユニオン」を持つことは何とか可能ですか?
  • ソリューション 3 でチェックサムを簡単に計算するにはどうすればよいですか?

ご意見やヒントをどうもありがとうございます。

クリス

4

1 に答える 1

2

申し訳ありませんが、コード例を書く時間があまりありませんが、簡単なヒントを提供しようとします. 1) パフォーマンスの問題。パフォーマンスの制約があるとすぐに、最初に最適化するのは、データの送信元であるストリームからの実際の読み取りの量です。File/Socket/etc が何であれ、とにかく QIODevice です。したがって、最初に行うことは、準備ができた試行/通知を受け取ったデータの処理ごとに QIODevice で利用可能なすべてのデータを追加する、ある種の QByteArray を維持することです。したがって、以下では、現在未処理のバイトを保持する特定の QByteArray m_rawData があると仮定します。これは、一部のテレグラム + 部分的に受信できる最後のテレグラムである可能性があります。

2)電報データを保持する Telegram のようなクラスを作成します。

class Telegram {
       QString       header;
       int           sequenceNumber;
       unsigned char checkSum;
       QByteArray    data;

       ...

       bool          checkSumOK();  // check is checksum is OK for provided data

}

好みに応じてコンストラクターと演算子を使用します (コピー コンストラクター/etc を実装できます)。次に、このクラスを ( <<, >>) 演算子で拡張して、パート 1 で説明した一時バッファーで動作する QDataStream をサポートします)。

したがって、一般的な概念は、できるだけ早くストリームから一時バッファーにデータを読み取り、読み取りが完了したら、結果のバッファーからできるだけ多くの Telegram のインスタンスをフェッチすることです。次に、QByteArray に適用された QDataSteam を使用して、4 バイトの読み取り、1 バイトの読み取りなどの呼び出しをパフォーマンスに大きな影響を与えることなく安全に使用できます。

3)もちろん、極端な状態について話している場合..整列された構造の上に生データを直接コピーするためにユニオン(前の回答で言及されているように)を考えることができますが、その方法にははるかに注意深いプログラミングが必要です(特にx32/x64 アーキテクチャとビッグ/リトル エンディアン プラットフォームを考慮)

于 2013-04-15T16:38:01.637 に答える