2011-02-04 18 views
11

私はソフトウェアで独自の通信プロトコルスタックを実装し始めていますが、どこから起動するのかはわかりません。私がこれまでにやっていない仕事の一種であり、最高の/推奨されるアプローチのためのリソースの面で助けを求めています。C/C++の実装通信プロトコル

私はc/C++を使用していますが、使用ライブラリ(BSD/BOOST/Apache)は自由に使用できますが、GPLは使用できません。私はC++を広範囲に使用しているので、C++の機能を使用することは問題ではありません。

プロトコルスタックは3つのレイヤーを持ち、すでに完全に指定され正式に検証されています。だから私がする必要があるのは、実装され、指定された言語で完全にテストされることです。また、プロトコルは非常にシンプルですが、信頼性の高い物理トランスポート層を介して異なるデバイス上で実行できます。私は、イベント、入力、出力、副作用、およびプロトコルステートマシンの動作を知っています。一般に、物理層から受信したメッセージを読み取ってそれを読み取って待機装置に送るために割込みが受信される。受信デバイスは、プロトコル層への応答メッセージを処理し、物理層上に送出することができる。

参考/おすすめのヘルプをいただければ幸いです。私はそれらを実装する方法を理解するのを助けるためだけに異なる言語を使用したいと思いますが、最終的には選択した言語に頼らざるを得なくなります。

更新:実装したいプロトコル例はSNEPです。

私は接続管理について心配する必要はありません。我々は、接続が確立済みであり、Iは、プロトコルが行うことが非同期(または同期)になると、プロトコルメッセージは既によく仕様

+1

この質問はあまりにも一般的です。その設計と実装を開始し、特定の問題についてのヘルプを依頼してください。 – peoro

+1

それは面白い仕事です。実装を設計するときは、単体テストで各レイヤーの独立テストをテストすることに注意してください。より具体的なヘルプを得るには、どこから始めるのか(PIOに接続されたピンを使っていますか?)、入手したいヘルプの種類を指定してください。 – harper

+0

私は@peoroに同意します。また、私はよく分からない - あなたはどこでこれを開発しているのですか?通常のプロトコル(イーサネット経由)では* OS *がネットワークスタックの下位レベルを処理します。プロトコル層と呼ばれるものを構築するOS APIを使用します。しかし、あなたがこれを構築しようとしている場所と、具体的に何が問題なのかを知らなければ、私は本当に助けることができません。 –

答えて

8

インターフェイスとメッセージから始めます。

ピアがメッセージを交換できるようにするセッションのインターフェイスを宣言します。単純な型(int、double、std :: string、std :: vectorsなど)を持つC++構造体としてメッセージを宣言します。例:

// these are your protocol messages 
struct HelloRequest { 
    uint32_t seq_no; 
    // more stuff 
}; 
struct HelloResponse { 
    uint32_t seq_no; 
    // more stuff 
}; 

// Session callback for received messages 
struct SessionReceiver { 
    virtual void connected(Session*) = 0; 
    virtual void receive(Session* from, HelloRequest msg) = 0; 
    virtual void receive(Session* from, HelloResponse msg) = 0; 
    virtual void disconnected(Session*) = 0; 
}; 

// Session interface to send messages 
struct Session { 
    virtual void send(HelloRequest msg) = 0; 
    virtual void send(HelloResponse msg) = 0; 
}; 

// this connects asynchronously and then calls SessionReceiver::connected() with a newly established session 
struct SessionInitiator { 
    virtual void connect(SessionReceiver* cb, std::string peer) = 0; 
}; 

// this accepts connections asynchronously and then calls SessionReceiver::connected() with a newly accepted session 
struct SessionAcceptor { 
    virtual void listen(SessionReceiver* cb, std::string port) = 0; 
}; 

これらのインターフェイスを使用するビジネスロジックをコーディングして、インターフェイスをテストします。インターフェースが必要なロジックを実装できると確信すれば、libeventやBoost.Asioのような好みのイベント駆動型フレームワークを使ってメッセージのインターフェースとシリアライズを実装します。

編集: インターフェイスではモックまたはテストの実装が可能です。また、インターフェイスの背後でシリアライゼーションが発生するということは、インプロセスピアの場合、メッセージをシリアライズおよびデシリアライズする必要がないため、そのまま継承することができます。

+0

私はこの提案が好きです。発生する可能性のある具体的な質問があればそれを調べて戻ってくるでしょう。 – dubnde

+0

マシン間で送信されることを意図したメッセージに 'struct'を使用していますか?私が知る限り、コンパイラは、著者がしばしばそれらがパックされると想定する方法で構造体をパックする必要はありません。少なくともコンパイラ指令を使用しない場合は、パディングはパフォーマンスなどのために挿入されます。データを受け取ったリモートホストがそれを再び構造体に読み込もうとすると、同じ構造体のレイアウトが同じであるという保証はありません。私はここに何か? – amn

+1

@amnこれらのメッセージはシリアル化され、デシリアライズされなければなりません。あなたはそれのためにGoogleのプロトコルバッファーまたは何かを使用することができます。 –

3

Boost.ASIOで定義されているデータ交換はかなりC++

におけるネットワーク通信を最先端であると仮定することができます
3

Google Protocol Buffersをご覧ください。説明から

プロトコルバッファは、構造化データをシリアライズするための柔軟で効率的な、自動化されたメカニズムです - XMLと思いますが、より小さく、より速く、かつ簡単。データを一度に構造化する方法を定義してから、特別に生成されたソースコードを使用して、様々なデータストリームとさまざまな言語を使用して構造化データを簡単に書き込んで読み込むことができます。あなたは、 "古い"形式に対してコンパイルされた配備されたプログラムを破壊することなく、データ構造を更新することさえできます。

プロトコルバッファは言語とプラットフォームに依存しないため、プロジェクトに合わせる必要があります。私はライセンスを見つけることができませんでしたが、少なくとも私が見つけることができるどこでも "GPL"とは言いません。

これはプロトコルに役立ちます。実際のデータ転送では、あなたがOSを自分で書いているのでなければ、使うべきプリミティブがあるはずです。もう少し詳しく説明しない限り、実装についてより正確なヘルプを与えるのは難しいです。たとえば、あなたはどのコミュニケーションチャンネルを使用していますか?イーサネット?

しかし、経験則として、できるだけ短いISRにする必要があります。この種のソリューションでは、通常、データをリングバッファにコピーすることを意味します。 ISRにメモリを割り当てる必要はありません。 ISRはデータをコピーした後、パッケージの上位層に通知する必要があります。 DMAを使用できる場合は、それを使用してください。その場合は、DMA転送を開始する前に通知を送信することができます。

特に、Linux Device Drivers,chapter 10をチェックしてみるとよいでしょう。ボトムと上半分についての部分をチェックしてください。

関連する問題