web-dev-qa-db-ja.com

ネットワークプロトコルを実装する方法は?

ここに一般的な質問があります。私はベストアンサーを探しているわけではありません。あなたの好きな習慣を表現してほしいのです。

Java(ただし、これはかなり一般的な質問です。C++でも同じ問題に直面しました)でネットワークプロトコルを実装したいのですが、これは以前と同じように初めてではありません。しかし、私はそれを実装するための良い方法が欠けていると思います。実際、通常はホスト間でテキストメッセージといくつかのバイトバッファを交換し、ステータスを保存して次のメッセージが来るまで待つことがすべてです。問題は、通常、さまざまなステータス/メッセージに反応するステートメントの場合、スイッチの束と多かれ少なかれ複雑です。通常、全体が複雑になり、管理が困難になります。出てくるものに「死角」があることは言うまでもなく、プロトコルのステータスを意味します。カバーされておらず、予測できない方法で動作します。各アクションの開始ステータスと終了ステータスを多かれ少なかれスマートにチェックするいくつかのステートマシンクラスを書き留めようとしました。私は行とタラの行を書かなければなりませんe考えられるすべての状況をカバーします。私が欲しいのは、良いパターン、または複雑なプロトコルのプログラミングで使用されるベストプラクティスのようなもので、管理と拡張が簡単で、非常に読みやすいものです。

あなたの提案は何ですか?

34
gotch4

Stateデザインパターンを読んで、多くのswitchステートメントを回避する方法を学びましょう。


「出てくるものに「盲点」があることもあります。つまり、プロトコルのステータスがカバーされていないことを意味します...」

状態ギャップを回避するのに役立ちます。それは良いデザインを保証することはできません、あなたはまだそれをしなければなりません。

「...考えられるすべての状況をカバーするために、1行と数行のコードを作成する必要があるためです。」

これを負担や問題と見なすべきではありません。考えられるすべての状況をカバーするコード行をmust書く必要があります。

Stateは、継承を活用できるため、役立ちます。それは良いデザインを保証することはできません、あなたはまだそれをしなければなりません。

16
S.Lott

プロトコルの設計は、通常、作業しているアプリケーションスペースがすべてです。たとえば、httpはすべてWebページ、グラフィックス、および投稿の処理に関するものですが、FTPはすべてファイルの転送に関するものです。

つまり、最初に、使用しているアプリケーションスペースを決定してから、実行する必要のあるアクションを定義する必要があります。そして最後に、実際のプロトコルの設計を開始する前に、やりたいことを実行する別のプロトコルスタックを真剣に、真剣に探し、プロトコルスタックの実装を完全に回避する必要があります。事前に構築されたものが絶対に機能しないと判断した後でのみ、独自のプロトコルスタックの構築を開始する必要があります。

6
Zak

C++では、Boost :: Spiritライブラリを使用して、プロトコルメッセージを簡単に解析できます。唯一の「難しさ」は、メッセージプロトコルの文法を定義することです。 Gnutellaのソースコードを見て、この問題をどのように解決するかを確認してください。ここで http://www9.limewire.com/developer/gnutella_protocol_0.4.pdf はGnutellaプロトコルの仕様です

3
miro

有限状態機械はあなたが望むものです

[〜#〜] fsm [〜#〜]

したがって、受信者または送信者として存在できる状態の全体を定義します(アイドル、connecting_phase1、connecting_phase2、パケットが必要です、...)

次に、考えられるすべてのイベントを定義します(packet1の到着、ネットのクローズなど)。

最後に、「状態xでイベントnが発生すると、関数yを実行して状態qに遷移する」というテーブルがあります-すべての状態とイベントについて(多くはnullまたは重複します)

編集-FSMの作成方法(ラフスケッチ)

 struct FSMNode
 {
      int m_nextState;
      void (m_func*);
 }
 FSMNode states[NUMSTATES][NUMEVENTS]=
   { // state 0
      {3, bang}, // event 0
      {2,wiz},
      {1, fertang}
    }
    {
      {1, noop}, // event 0
      {1, noop},
      {3, ole}
     }
     .......
     FSMNode node = states[mystate][event];
     node.m_func(context);
     mystate = node.m_nextState;

これは無効な構文でいっぱいだと確信していますが、ドリフトが発生することを願っています

3
pm100

プロトコルとしてXMLを使用してみませんか? XMLノード内のすべてのデータをカプセル化して分類できます

2
Andres

自分で例をあげることはできませんが、他の(有能な)人々がそれをどのように行っているかを見てみませんか?

このように? http://anonsvn.jboss.org/repos/netty/trunk/src/main/Java/org/jboss/netty/handler/codec/http/

P.S.さらに言えば、実際には、ネットワークフレームワークとしてnettyを使用し、その上にプロトコルを構築することをお勧めします。それは非常に簡単なはずです、そしてあなたはおそらくたくさんの頭痛を取り除くでしょう...

2
Enno Shioji

Javaを使用している場合は、 Apache MINA を検討してください。そのドキュメントとサンプルは、正しい方法であなたを刺激するはずです。

1
incarnate

システムトレイのネットワーク接続アイコンを右クリックします。 [問題のトラブルシューティング]をクリックします。トラブルシューティング担当者が問題を見つけて修正する場合があります。この場合、ビジネスをすぐに開始できます。トラブルシューティングでWinsocksの問題を修正できない場合は、「このコンピューターに1つ以上のネットワークプロトコルがありません」のようなエラーが発生する可能性があります。

0
mark