web-dev-qa-db-ja.com

ファイルまたはTCPを介したローカルクライアントサーバー通信?

PythonクライアントがC++でサブプロセスを起動しています。

C++プログラムは、Pythonクライアントに結果を報告する必要があるいくつかのスレッドを実行します。

PythonクライアントとC++サブプロセスの両方が同じマシンで実行されていることを知っている場合、それらの間で通信するための最良の方法は何ですか?TCPまたはファイルを通して?

ファイルを介した通信とは、C++側がその結果をPythonクライアントが検索して解析するいくつかの異なるJSONまたはXMLファイルに書き込むことを意味します。

ファイルを介して通信するのは悪い設計ですか? TCP=を使用していますか?コンピュータにソリッドステートドライブがある場合はどうなりますか?

編集:私はパイプ(stdin、stdout)を使用してしまいました。この投稿を参照してください: https://stackoverflow.com/questions/36748829/piping-binary-data-between-python-and-c

5
Chuque

あなたがやろうとしていることは、IPC、または プロセス間通信 のメソッドを定義することです。これには多くの方法があります。

一般に、IPCの最善の方法には、次の利点があります。

  • 標準化されているため、他の開発者がコードを見て理解できます。
  • エラー検出メカニズムを含む堅牢。
  • プラットフォーム(OS、プログラミング言語など)でサポートされています。
  • 単純で、フレームワークレベルのコードをほとんどまたはまったく必要としません。

これらの理由から、私は通常TCP/IPを選択します。

  • それは非常に標準化されており、誰もがそれがどのように機能するかを知っているべきです。
  • エラー検出およびACKメカニズムが組み込まれています。
  • ほとんどすべての最新プラットフォームでサポートされています。
  • ほとんどのライブラリ実装は単純です。エンドポイント情報を提供し、ストリームを取得します。
  • クライアントとサーバーは現在同じマシン上にあります。将来の要件によってこれが変更された場合は、接続情報を変更するだけで問題なく機能します。

TCP/IP通信のペイロードに関する限り、XML、JSON、シリアル化されたオブジェクトなど、都合のよいものであれば何でもかまいません。ただし、通常は言語を混在させる場合、プラットフォームに依存せず、人間が読める(デバッグを支援する)XMLまたはJSONのようなものを使用します。

データを生成または消費するモックにストリームを接続できるテストケースを作成することも強くお勧めします。そうすれば、完全なクライアント/サーバーシステムを稼働させておく必要なく、両端でインターフェースをテストできます。


文字通り他に方法がない限り、ファイルを使用して通信しないでください。この答えは短く簡潔にしたいので、これを言います。私はファイル駆動型のインターフェースを扱ってきました。私は毎回それを嫌い、いつもそれを行う別の方法があるかどうか尋ねました。これはエラーが発生しやすく、扱いにくいものです。

6
user22815

デフォルトは StandardIO です。

作業を行うために新しいプロセスを作成したり、状態を再作成したりするオーバーヘッドを回避する必要がある場合は、ソケットを使用します。移植性と拡張性が懸念される場合は、TCPソケットを使用してください。ソケットが必要な場合は、TCPソケットをデフォルトにする必要があると主張できますが、しません!)

しかし、より重要なのは、標準IOの「標準」が駄洒落ではないことを忘れないでください!標準ストリームは自動的に表示され、使いやすく、ほとんどどこでも利用できます。


これは注目に値します。これはユースケースのように聞こえるので、ほとんどの言語が子プロセスの生成とSTDIOを介した子プロセスとの通信をほぼ同じくらい簡単にするライブラリを提供することです。

2
svidgen

SOCK_STREAMソケットペアを作成することをお勧めします。ソケットペアの利点は、パイプとは異なり、双方向であることです。一部のオペレーティングシステムでは、パイプも双方向ですが、これに依存しないでください。

ソケットペアのもう1つの利点は、ポート番号やファイル名などの一意の識別子が必要ないことです。

これを実際に実装する方法:C++プロセスは、ソケットペアの最後のファイル記述子を認識する必要があるため、その整数をコマンドライン引数として渡すことができます。

要件が変更され、C++プロセスがPythonプログラムではなく)個別に起動される場合、Unixドメインソケットを使用して、常にソケットの名前を付けることができます。

また、要件がさらに変化し、C++プログラムが別のマシンで実行される場合、TCPを使用するように変更するのは比較的簡単です。

SOCK_STREAMソケットは必ずしもメッセージのサイズを保持しない場合があることに注意してください。したがって、メッセージが個別のバイトではなくバイトのブロックである場合は、ネットワークバイトオーダーのブロック長をメッセージの先頭に追加する必要があります。これにより、読み取りが必要なバイト数がリーダーに確実に通知されます。

1
juhist