web-dev-qa-db-ja.com

言語間コミュニケーション

2つの異なる言語で書かれたフロントエンドとバックエンドを持つプログラムがある場合、これら2つのシステムはどのようにして相互に通信しますか?私はプログラミングの専門的な経験がなく、まだ学校に通っています。たとえば、必要に応じて2つのJavaプログラム間で通信する方法を知っています。2つの異なるマシンに2つのプログラムがある場合、ソケットとストリームを使用できます。しかし、それらのプログラムが異なる言語で書かれていますか?おそらくファイルを使用できますが、他の方法で通信できますか?

私はこれについていくつかの調査を行ってきましたが、答えを完全に特定することはできません。ご協力いただきありがとうございます。

1
namarino

2つのプログラム(プロセス)間の通信には、 プロセス間通信 (IPC)が必要です。

ソケットは、単一のマシンでのプロセスにもよく使用されます。たとえば、HTTPサーバーとREST API)には、この方法で使用できるツールがたくさんあります。ソケットの利点は、グローバルアドレス(ポート番号)を持っているため、どのようなプロセスでも可能です。接続を確立できます。

特に、後で処理されるメールボックスのようなディレクトリが使用されている場合は、ファイルを介した通信が使用されることがあります。実際には、これはかなり複雑です。書き込みプロセスでは一意のファイル名を使用する必要があり、受信プロセスではディレクトリを監視する必要があります。そして、答えを送る簡単な方法はありません。

ローカルプロセスの場合、主要な通信メカニズムはパイプです。パイプは、オペレーティングシステムによって提供される匿名の単方向ストリームです。パイプは nixライクなオペレーティングシステムでは特に重要です Linuxのように、多くのツールがstdinからデータを消費し、出力をstdinに書き込む方法で記述されています。これにより、そのようなツールの多くを より大きなパイプラインにチェーン化 にすることができます。アプリケーションにとって、パイプは通常の入出力ストリームとして表示されます。

パイプは匿名であるため、アプリケーションは既存のパイプに接続できません。代わりに、パイプは親プロセスによって作成されます。親が子プロセスを生成すると、パイプ(およびその他のファイル記述子)は親から継承されます。親と子の間、または2つの兄弟プロセスの間の双方向通信では、パイプのペアを作成するのが一般的です。プロセスが生成された後、各通信パートナーはパイプの一方の端を閉じるため、各プロセスには読み取り用のパイプと書き込み用のパイプが1つずつあります。

かなり低レベルの通信方法は共有メモリです。オペレーティングシステムには、複数のプロセスから一定量のメモリを見えるようにする機能があるため、誰でもそのメモリ領域に対して自由にデータを読み書きできます。ただし、すべてのプロセスがバイナリ形式に同意し、同期プロトコルを使用して、互いの変更を上書きしないようにする必要があります。これらの問題にもかかわらず、複数のプロセスが同じデータを非常に効率的に変更する必要がある場合は、共有メモリが良い解決策になることがあります。それ以外の場合は、データを管理し、データへのアクセスと変更の要求を(ソケットなどを介して)受け入れるサーバーを作成するのが一般的です。

5
amon

2つのJava=プログラムを開始点として、これらのプログラムは両方ともメッセージのフォーマットに暗黙的に合意しました。たとえば、8ビットから1バイト、非常に多くのバイトから1つのワード、パケット、およびパケット内の特定の単語の意味は何ですか。

ただし、その合意が得られたら、エンドポイントが同じ方法でデータを入力および解釈する限り、エンドポイントがどの言語で記述されているかは問題ではありません。したがって、異なる言語で書かれたプログラムはパケットを交換でき、誰もが幸せです。

現在、これらのパッカーのコンテンツは、両端が同意することを意味するより高いレベルを持つこともできます。コンテンツは、生のバイナリデータ、単純なテキスト文字列、またはHTTPメッセージやXMLまたはJSONデータなどの高レベル構造としてフォーマットすることもできます。しかし、両端の意味についての合意が重要です。

唯一注意が必要なのは、2台の異なるマシンが異なる エンディアン と通信している場合です。これは、データが物理的な伝送媒体に到達したときにのみ問題になります。その時点で、network byte orderの合意を通じてこれを行うための標準的な解決策があります(前のリンクを参照)

1
Peter M

これは実装固有です(特に [〜#〜] abi [〜#〜]呼び出し規約 固有)。

多くの言語実装では、他の言語(多くの場合C)の関数(同じプログラムおよび process )を呼び出す方法が提供されています。 外部関数インターフェースと呼ぶことができます。

Javaの場合は、 [〜#〜] jni [〜#〜] についてお読みください。

Pythonについては、 Extending&Embedding Python Interpreter について読んでください。

Ocamlについては、 CとOcamlのインターフェース に関する章を読んでください。

等....


しかし、それらのプログラムが異なる言語で書かれた場合はどうでしょうか?ファイルを使用することも考えられますが、他に通信方法はありますか?

はい、それは プロセス間通信 と呼ばれます。 Linuxは、 システムコールsyscalls(2) ...にリストされています)、 pipe(7) -sを介してそれを行う多くの方法を提供します、 socket(7) -s、 signal(7) -s、 shm_overview(7)sem_overview(7) などなど...

また読む オペレーティングシステム:3つの簡単な部分

「書き込み」!=「通信できる」

たとえば、必要に応じて2つのJavaプログラム間で通信する方法を知っています。2つの異なるマシンに2つのプログラムがある場合、ソケットとストリームを使用できます。しかし、それらのプログラムが異なる言語で書かれていますか?ファイルを使用することも考えられますが、他にコミュニケーションの方法はありますか?

2つのプログラムが同じ言語で記述されていても、異なる言語で記述されていても、同じ手法を使用します。

システムが通信できる言語は、それがで書かれた言語とは何の関係もありません。たとえば、ChromeブラウザはC++で記述されていますが、「話す」言語はHTTPです。Webサーバーは、HTTP仕様に準拠している限り、次の言語で記述できます。どの言語でも機能します。HTTPを介して通信できるライブラリを備えた言語はたくさんあります。

EDI、ODBC、SMTPなどの他の通信プロトコルについても同様です。 Wireshareを使用して、ネットワーク経由で送信されているものを確認する場合、JavaまたはC++コードは表示されません。プログラムが記述されている言語はまったく関係ありません。

実際、c ++またはJava=をネットワーク経由で渡すプロトコルがあった場合、2つの大きな問題が発生します。

(1)ほとんどのプログラムは実行時に、それらが記述されている言語さえ理解していないため、処理するのは非常に困難です。 コンパイラはその言語を読み取ることができますが、機械語またはある種の中間言語(JavaのバイトコードまたはC#の場合はIL、インスタンス)。ランタイムがソースコードをまったく理解しない場合がよくあります。

(2)そのようなプロトコルを介して送信されたものはすべて インジェクション攻撃 に対して広く開かれるため、セキュリティが非常に危険にさらされます。

1
John Wu

考えられる解決策の1つは、ソケットを介したデータのストリームです。異なる言語で記述された2つのプロセスに対しても、両方がJavaで記述されているかのように機能します。

ソケットは、従来、基盤となるオペレーティングシステムやOSの標準ライブラリの仕様によって提供されてきました。また、従来、ほとんどのプログラミング言語ランタイムは、OSが提供するソケット実装とインターフェイスできるライブラリを提供します。

したがって、その場合を想定しましょう。ローカルまたはネットワークソケットを使用して、実行中のCプロセスと実行中のJavaプロセスを一緒に接続できるとします。

あなたの本当の質問は、何がソケットを通過するのかということです。

答えは:あなたが望むものは何でも。オペレーティングシステムはビットをやり取りします。これらのビットがプロセスにとって何を意味するかを決定する必要があります。

例としては、BSON、XML、プロトコルバッファ、Unicode、圧縮されたWordドキュメント、PNG画像などがあります。ソケットのデータを読み書きするJavaおよびCプログラムをコーディングして、データの処理方法とその意味を知るのは、プログラマとしてのあなた次第です。

1
RibaldEddie

これに対する一般的に受け入れられている最も基本的なアプローチは、REST APIを作成することです。データ形式としてJSONを使用すると、作業が簡単になります。

0
TheCatWhisperer