いくつかの組み込み通信を処理するためにコードを書き直しています。現在、プロトコル処理は、大きな case/switch ステートメントを含む While ループに実装されています。この方法は少し扱いにくそうです。通信プロトコルを実装するために最も一般的に使用されるフロー制御方法は何ですか?
4 に答える
「while + スイッチ/ケース」はステートマシンの実装のようです。よく考え抜かれたステートマシンは、多くの場合、プロトコルを実装する最も簡単で読みやすい方法だと思います。
ステートマシンに関して言えば、従来のプログラミング ルールのいくつかを破ることには、領域が伴います。「すべての関数は 25 行未満にする」などのルールは機能しません。ステートマシンは変装した GOTO であると主張する人さえいるかもしれません。
これは、使用している言語と、利用可能なデータセット オブジェクトの種類に大きく依存すると思います。
たとえば、Python では、すべての異なる処理ステートメントの Dictionary オブジェクトを作成し、それを繰り返し処理して、呼び出す正しいメソッド/関数を見つけることができます。
Case/Switch ステートメントは悪いことではありませんが、巨大になると (大量のプロトコル ハンドラーでできるように)、扱いにくくなる可能性があります。
プロトコル ヘッダーのフィールドをキーオフして、そのプロトコルの処理の次の段階に進む場合は、関数ポインターの配列を使用できます。プロトコル ヘッダーの値を使用して配列にインデックスを付け、そのプロトコルの関数を呼び出します。
無効な値も含め、この配列で可能なすべての値を処理する必要があります。最終的には、誰かが攻撃を試みているか、プロトコルの将来のリビジョンが新しい値を追加するため、無効な値を含むパケットを取得します。
処理されるプロトコルがすべて 1 つの場合は、switch/case ステートメントが最善の策かもしれません。ただし、個々のメッセージ ハンドラをすべて独自の関数に分割する必要があります。
switch ステートメントに実際にメッセージを処理するコードが含まれている場合は、メッセージを分割するよりも良いでしょう。
複数の同様のプロトコルを処理している場合は、同じ抽象クラスに基づいてそれぞれを処理するクラスを作成し、接続が開始されたときに、それがどのプロトコルであるかを判断し、適切なハンドラー クラスのインスタンスを作成して、通信をデコードして処理することができます。 .