10

私が一緒に働いている開発チームの一部は、私たちの製品と統合するためのサーバーを作成するという課題を与えられました。C SDK を提供する低レベルのセンサー デバイスがいくつかあり、データを収集する人々が使用できるようにそれらをネットワーク経由で共有したいと考えています。シンプルですね。誰かが建物の一部にある自分のマシンにセンサー デバイスを接続し、サーバーを実行して、デバイスをネットワークの他の部分と共有します。次に、クライアントがアプリケーションを介してそのサーバーに接続し、デバイスからセンサーの読み取り値を収集します。

私は単純で言語にとらわれないネットワーク プロトコルと、Java での参照実装を作成しました。問題は、C で記述された SDK のみを提供するデバイスで動作する実装を作成することです。次のことを考えていました。

  1. 接続されている各デバイスから最新の測定値を収集して保存するポーリング スレッドを作成します。
  2. マルチスレッド サーバーを使用して、ワーカー スレッドへの各着信接続をスピンオフします。
  3. ワーカー スレッドがセンサー読み取りの要求を受信すると、ポーリング スレッドによって収集された最新の値がクライアントに返されます。

これは、特に C では多くのスレッド化です。したがって、一般的な要件を確認すると、次のようになります。

  • Windows XP/Vista、Linux、および OS X マシンで実行
  • C または C++ で書かれており、私たちが持っている C SDK と対話します
  • 可変数の同時接続 (ワーカー スレッド) を受け入れる
  • フォークではなく、スレッドを使用する必要があります (IPC の別のレイヤーを処理したくない)

使用を開始するためのライブラリと、できればサンプルコードを提案できる人はいますか?

4

11 に答える 11

13

Boost.ThreadBoost.Asioを使用して、Windows および Linux システムでマルチスレッド サーバーを構築しました。チュートリアルにより、簡単に始めることができました。

于 2008-12-20T14:57:53.130 に答える
9

このようなサーバーを作成する最善の方法は、サーバーを作成するのではなく、システムを再設計して不要にするか、既存のコンポーネントを再利用することです。なぜなら:

誰かが建物の一部にある自分のマシンにセンサー デバイスを接続し、サーバーを実行して、デバイスをネットワークの他の部分と共有します。

これには、コードに脆弱性がある場合、マシン全体をネットワークの残りの部分と共有する可能性もあります (C++ でゼロから記述し、新しいプロトコルを発明しているため、おそらくそうなるでしょう)。

だから、それを逆にしてください。センサー ハードウェアを備えたマシンに単純なクライアントをインストールし、それを常時または定期的に実行して、結果を中央サーバーにプッシュ (ポスト) します。中央サーバーは、標準の Web サーバーでもかまいません。または、データベースである可能性があります。(これらは両方ともすでに書かれていることに注意してください-車輪を再発明する必要はありません;-)

その後、アプリケーションは今考えているのと同じように動作しますが、センサーではなくデータベースからデータを収集します。ただし、センサーを備えたマシン上で実行される部分は、マルチスレッドのカスタム サーバーの悪夢から、発信接続のみを行い、cron (または Windows で同等のもの) から実行できる素敵な小さなシングル スレッドのコマンド ライン クライアントに縮小されました。 )。

リアルタイムのデータ収集が必要な場合でも (そして、あなたの説明からはそうではないように思えます)、センサー コレクターはサーバーではなくクライアントである方がよい場合があります。中央コレクター (またはそれらのグループ) への長期接続を開き、データを提供する指示を待ちます。

編集:ceretullisとpukkuの回答は、マルチキャストを使用したこれの素晴らしいバリエーションを示唆しています-この回答とコメントを参照してください

于 2008-12-20T16:04:28.597 に答える
7

Douglas Schmidt の ACE (Adaptive Communications Environment)は、高性能マルチスレッド サーバーを構築するための成熟した、 移植性の高いオープン ソース フレームワークです。主に通信アプリケーションを対象としていますが、さまざまなプロジェクトで使用されています。また、 TAOと呼ばれるオブジェクト リクエスト ブローカーも付属しています ( CORBAを使用している場合) 。

フレームワークの名声の 1 つは、多くのスレッド モデル (スレッド プール、要求ごとのスレッド、非同期 + スレッドなど) をサポートしているため、アプリケーションに最適な方法でスレッド管理を使用できることです。これは実際、このシステムの最も興味深い機能です。サーバー フレームワークの機能は、すぐに使用できます。ここで提案されている他のライブラリのほとんどは、この機能の多くを自分で実装する必要があります。

かなりの量の電子ドキュメントがあり、それについて書かれた本もいくつかあります。これは最も暖かくふわふわしたシステムではなく、実際には快適さよりも速度を重視して構築されていますが、C++ を使用しています。おそらく、機能を再構築してすべての同期をデバッグしようとするよりも、ACE に頭を悩ませる方がはるかに労力がかからないことがわかるでしょう。

ああ、ちなみに、スピーチと同じように、そしてビールと同じように自由です。商用ルートが必要な場合は、サポートとメンタリング サービスを提供するコンサルタントのエコシステムもあります。いくつかのコード スニペットを含むチュートリアルは、こちらにあります。

于 2008-12-20T15:13:58.807 に答える
4

QTを使用します。クロスプラットフォームのスレッドをサポートしています。良いドキュメント:

QT スレッディングのドキュメント

それらのシグナル/スロット メッセージング メカニズムは、スレッド間でもシームレスに機能します。

于 2008-12-20T14:58:16.297 に答える
4

あなたの質問に対する答えではありませんが、実際には C/C++ よりも Java に精通しているように思われるので、参照実装を続けてJava Native Interfaceを使用して SDK に接続してみませんか。(実際に使ったことはありませんが、まさにこのような状況に役立つと思いました。)

または、SDK を使用する単純な C プログラムを簡単に作成し、ソケットベースのストリームなどを使用してデータを Java プログラムに送信することもできます。このようにして、Java でより難しい処理を行うことができます。

于 2008-12-20T15:01:03.717 に答える
3

また、(プロジェクトのWebサイトによると)「ローカルおよびワイドエリアネットワーク全体の障害に強い高性能メッセージングサービスを提供するオープンソースツールキット」であるSpreadToolkitをお勧めします。私はあなたと非常によく似た状況でそれを数回使用しました。基本的に、frankodwyerが提案するサーバーを提供します。

Spreadデーモン(つまり、サーバー)はマルチスレッドではありませんが、非常に高速で、少なくとも数百または数千のクライアントまで拡張できます。さらに、このプロトコルは信頼性の高いIPマルチキャストに対応しており、(マルチクライアント環境では)ポイントツーポイントTCPまたはUDP接続のみを使用して実装されたものに対して(パフォーマンス的に)明確なエッジを提供します。(しかし、信頼できるIPマルチキャストを自分で実装しようとしないでください...どうやら、Spreadプロジェクトは副産物として多くのPhD / MSc論文を作成しました-または、主な重点を置いている間、副産物であるツールキットですか?常に学術研究でしたか?私にはよくわかりません...)。

SpreadにはCおよびJavaクライアントAPI(およびPython)があるため、問題に非常によく一致しているように思われます。2つのライセンスモデルがあります。最初の選択肢はBSDに近いものです。そしてもちろん、それはクロスプラットフォームです(クライアントとサーバーの両方に関して)。

ただし、Spreadは(もちろん)すべてを行うわけではありません。最も顕著なのは、おそらく永続性を行わないことです(つまり、クライアントがオフラインであるか、メッセージを受信できない場合、Spreadは少なくとも非常に少数のメッセージを超えてメッセージをバッファリングしません)。しかし、幸いなことに、Spreadが保証するものに加えて、独自の永続性の実装をロールすることはそれほど難しくありません(そのような問題があなたにとって重要かどうかさえわかりません)。次に、Spreadはメッセージをそれぞれ100キロバイトに制限しますが、送信者が大きなメッセージをいくつかの小さなメッセージに切り刻み、受信者でそれらを連結するだけで、その制限を回避することも非常に簡単です。

于 2008-12-20T17:36:18.333 に答える
2

libeventを使用して、ネットワーク I/O を多重化しています。Boost.Asio の代替として検討する必要があります。

libevent API は、ファイル記述子で特定のイベントが発生したとき、またはタイムアウトに達した後に、コールバック関数を実行するメカニズムを提供します。現在、libevent は /dev/poll、kqueue、イベント ポート、select、poll、および epoll をサポートしています。

于 2009-08-23T06:54:36.040 に答える
1

私はfrankodwyerに同意し、プロトコルをプルモデルからプッシュモデルに切り替えます。

共有サービスが実行されているときはいつでも、センサーが接続されているコンピューターに、100Hz(またはセンサーの場合以降)でUDPマルチキャストを介して読み取り値をブロードキャストさせます。次に、マルチキャストデータを読み取るクライアントを作成します。

または、マルチキャストの代わりにブロードキャストUDPを使用することもできます。

ところで、これはGPS、Lidar、およびその他のセンサーが処理を実行する数です。

于 2008-12-20T17:17:20.990 に答える
0

クロスプラットフォーム API を使用するか、各アーキテクチャで変更する独自の API を作成します。

これも修正してください: http://www.goingware.com/tips/getting-started/

于 2008-12-20T14:52:29.163 に答える
0

C (C++ ではなく) を使用したい場合は、NSPR ライブラリが必要なものを提供する可能性があります...

于 2008-12-20T15:12:03.710 に答える
-2

プロトタイプのデザイン パターンを検討することを強くお勧めします。

私はこのパターンを使用して、プロトコルに依存しないサーバーを C++ で作成しました。このサーバーは、HTTP Web サービスから独自の独自のバイナリ プロトコルまで、あらゆるものに使用してきました。

基本的に、アイデアは次のとおりです。

サーバーは、特定のポートで着信接続を受け入れ、それらの接続を処理するスレッド (またはプロセス) を作成します。

汎用サーバーを構築しようとしているとき、プロトコルに関する仮定を行わずにデータを読み書きすることは実際にはできないことに気付きます...そのための秘訣は、プロトタイプ パターンを使用することです。

純粋な「HandleConnection() = 0」メソッドを使用して「ConnectionHandlerBase」クラスを作成します。サーバー クラスのユーザーを独自の実装でこのクラスのサブクラスにします。さらに、このクラスは、それ自体のコピーを返す「Clone()」メソッドを実装しています...このようにして、サーバーはそのタイプを知る必要なく、その新しいインスタンスを作成できます...そして、接続を取得したら、「Clone」を呼び出します()" をプロトタイプ インスタンスに追加し、処理スレッドにこのオブジェクトの "HandleConnection()" を呼び出してもらいます。

アプリケーションの起動時に、サーバー クラスのユーザーは次のように呼び出す必要があります。

"Server.AttachConnectionPrototype( &MyConnectionObject );"

于 2008-12-20T15:19:31.557 に答える