2

Net.Sockets.Socket クラスを使用して TCP サーバーを記述します。TCP はストリーム上で動作するため、メッセージを互いに分離するアプローチが必要です。(詳細については、こちらのブログで Stephen Cleary のメッセージ フレーミングの投稿を参照してください。)

私が達成したいのは、カスタム メッセージ フレーミング プロトコルをサポートする TCP サーバー クラスを作成することです。このクラスの初期化の例は次のとおりです。

var receiveDelimiter = Encoding.UTF8.GetBytes("[END]");
var sendDelimiter = Encoding.UTF8.GetBytes("\r\n");
var protocol = new DelimiterFramingProtocol(receiveDelimiter, sendDelimiter);
var server = new Server(protocol);
server.Start(port);

プロトコルは抽象クラス MessageFramingProtocol から派生する必要があり、サーバーはそれを使用してメッセージを分離できる必要があります。上記の例では、サーバーは区切り文字 ("[END]") が受信された場合にのみ DataReceived イベントを発生させ、DataReceived の引数には区切り文字の前にあるメッセージの部分のみを含める必要があります。デリミタの後にさらにバイトが受信された場合、サーバーはそれらを保存し、デリミタが再度受信されたときにのみ DataReceived を起動する必要があります。サーバーは、送信するすべてのメッセージの後に sendDelimiter も送信する必要があります。

私が必要としているのは、このサーバー クラス全体でも、プロトコル クラスでもありません。必要なのは、テンプレート、デザインのアドバイスです。サーバー クラスに Protocol という名前の FramingProtocol タイプのプロパティがあると仮定すると、Server クラスで操作を送受信するときにそれを使用するにはどうすればよいでしょうか? 上記の柔軟性を提供するために必要な抽象メソッド/プロパティは何ですか? FramingProtocol から派生するカスタム プロトコル クラスを記述できるはずです。区切り文字、長さのプレフィックス、それらの両方、またはその他のカスタム アプローチを使用して、メッセージを区切ることができます。

4

1 に答える 1

1

サーバーに渡される Protocol インスタンスを 1 つだけにするつもりはありません。多数のインスタンスが必要になります。サーバーに、新しい Protocol インスタンスを作成するか、起動時に作成されていっぱいになったプールからそれらをデプールするファクトリ クラスを提供します。

私が通常行うことは、次のようなものです。

RX: 'int Protocol::addBytes(char *data,int len)' 関数を提供します。生の rx データのアドレスと長さを入力すると、関数は -1 (プロトコル ユニットを完全に組み立てずにすべての生データを消費したことを意味します)、またはその時点で消費されたデータのインデックスである正の整数を返します。有効な PDU を組み立てました。インスタンスが PDU を組み立てることができた場合、さらに処理することができます (たとえば、「DataReceived(Protocol *thisPDU)」イベントを発生させ、新しい Protocol インスタンスを作成 (またはデプール) し、残りの生データをロードします。 .

TX: (かなりオーバーロードされている可能性があります)、「bool Protocol::loadFrom(SomeDataClass * outData, OutStreamClass *outStream)」メソッドを提供します。このメソッドは、シリアル化されたデータを生成するための完全なデータ セットが存在するように、任意のソースから内部メンバー vars にデータをロードできます。 PDU、(およびfalseを返すか、問題がある場合は例外を発生させます-たとえば、提供されたデータがサニティチェックに失敗します)。エラーが検出されない場合、インスタンスは、渡された「outStream」ストリーム/ソケット/バッファー+len からシリアル化されたデータを駆動します。

于 2012-08-02T15:04:41.170 に答える