4

私は最近、カスタム シリアル通信プロトコルのコードを書いていました。私がしたことは、受信データの一部 (8/16 ビット) を使用して、フレーム サイズの大きさを示すことでした。このデータに基づいて、次のデータはないと予想しています。Crc を使用してフレームを承認または拒否します。しかし、受信側では、フレームを処理する前に、予想されるデータ量を知る必要があるため、Crc にフレーム長データを含めることはできません。

私が直面した問題は、このフレーム長のデータが破損し、受信側の配列サイズがそれよりもはるかに小さいのに対し、受信側がそのバイト数を受信するようにだますことです。これにより、連続したメモリ位置に存在する多くの重要なシステム変数が破損します。

バッファ オーバーフローが発生しないようにするにはどうすればよいですか? これに関する私の考え 1) フレーム長データが特定の値を超えた場合は拒否します。2) 最大数を制限するデータ型を使用します。配列インデックスの範囲を 256 のメモリ ロケーションに制限する short を使用するように、280 バイトのバッファを作成します。3) メモリを別の場所に割り当てて、重要なシステム変数に影響を与えないようにします。

受信ループに陥るのを防ぐために使用したことの 1 つは、タイムアウトを使用することです。しかし、私はこの問題のこの側面を見落としていました。コードはより大きなシステムコードの一部であり、私はここの専門家ではないため、問題を確認して再現する時間があれば、私にはよく見えます。

一般的に、この種の問題を安全に処理するにはどうすればよいですか?

また、オーバーフローを防ぐために、配列を使用する際に従うべき一般的な考慮事項または標準的な慣行は何ですか?

4

2 に答える 2

1

この問題を最小限に抑えるために使用できるものはたくさんありますが、一般的に、これに対する万能のソリューションはありません。決定を下し、何か問題が発生した場合に何が起こるかを理解し、システムがそれを処理できるようにする必要があります。

システムに最適なものを正確に把握する必要があります。たとえば、メッセージが 256 を超えると予想されない場合、バッファーのサイズを 0xFF として宣言し、バッファーのインデックスを uint8_t として宣言すると、一度に 1 バイトずつ挿入することでそれを超えることはできなくなります。 256 に到達することはなく、オーバーフローして 0 に戻ります。これの欠点はもちろん、これが発生した場合、受信したデータの一部を上書きすることですが、ほとんどの場合、crc チェックでエラーが明らかになるはずです。

他にできることは、データ長をバッファの最大値と比較し、バッファを超えている場合はメッセージを保存しないことです。したがって、データ長が大きすぎて受信したメッセージは完全に拒否しますが、データを保存することはできません。明らかに、データ長が頻繁に破損する場合、これには多くの問題があります。

正直なところ、最善の方法は、カスタム シリアル通信プロトコルを再考することです。発生しているエラーをうまく処理しているようには思えません。メッセージの最初と最後に同期バイトを配置して、実際に適切なデータを受信して​​いることを確認し、メッセージ全体を問題なく CRC し、ネットワークを通過する最大データ パケット サイズを定義して、送信するパケット数を通知できます。受ける。通信プロトコルがあまり良くない場合は、根本から考え直す必要があります。

于 2016-04-09T19:55:15.427 に答える