38

同じシステム上に 2 つのアプリケーションがあり、相互に通信する必要があります。私の調査から、これはプロセス間通信と呼ばれ、socketpair() の使用が私の問題に対する最良の方法であると考えています。

私は、C で socketpair() を使用してソケットを作成することから始めようとして、(文字通り) 髪を引き裂いています。私が理解していることから、ソケットは非常に複雑なトピックであり、初心者の C プログラマーであることは確かに状況を助けていません。

過去 48 時間、Google で検索したり、チュートリアルを読んだりしましたが、まだ取得できません。概念は理解できますが、コードがわかりにくいです。http://beej.us/guide/bgnet/html/single/bgnet.htmlの記事を何度か読みましたが、単純ではありません。

誰かがいくつかの例を提供できますか(5年生が理解できるほど簡単です)、または良いチュートリアルを教えてくれますか?

4

4 に答える 4

71

socketpair次のように、両方のプロセスを作成する場合にのみ使用できます。

  1. call socketpair- これで、2 つのソケット ファイル記述子 (1 つのパイプの両端) ができました。
    • 一方のエンドをエンドに指定し、もう一方をエンドに指定します。どちらでもかまいません。選択して、後でそれに固執するだけです
  2. 呼び出しfork- これで 2 つのプロセスができました
    1. forkゼロが返された場合、あなたは子供です。ファイル記述子を閉じ、記述子を保持し、それをこのプロセスのパイプの終わりとして使用します
    2. forkゼロ以外が返された場合、あなたは親です。ファイル記述子を閉じ、ファイル記述子を保持し、それをパイプの終わりとして使用します
  3. 2 つのプロセスがあり、それぞれが同じパイプの異なる端を表す 1 つのファイル記述子を持っています。両方のプロセスが同じプログラムを実行していることに注意してくださいforkがそのwriteソケットで呼び出すと、子はソケットからそのデータを読み取ることができ、その逆も同様です。

コードへの直訳は次のとおりです。

void child(int socket) {
    const char hello[] = "hello parent, I am child";
    write(socket, hello, sizeof(hello)); /* NB. this includes nul */
    /* go forth and do childish things with this end of the pipe */
}

void parent(int socket) {
    /* do parental things with this end, like reading the child's message */
    char buf[1024];
    int n = read(socket, buf, sizeof(buf));
    printf("parent received '%.*s'\n", n, buf);
}

void socketfork() {
    int fd[2];
    static const int parentsocket = 0;
    static const int childsocket = 1;
    pid_t pid;

    /* 1. call socketpair ... */
    socketpair(PF_LOCAL, SOCK_STREAM, 0, fd);

    /* 2. call fork ... */
    pid = fork();
    if (pid == 0) { /* 2.1 if fork returned zero, you are the child */
        close(fd[parentsocket]); /* Close the parent file descriptor */
        child(fd[childsocket]);
    } else { /* 2.2 ... you are the parent */
        close(fd[childsocket]); /* Close the child file descriptor */
        parent(fd[parentsocket]);
    }
    exit(0); /* do everything in the parent and child functions */
}

これは単なるサンプル コードであることに注意してください。エラー チェックと実用的なストリーム プロトコルはすべて省略しています。


2 つの別個のプログラムが通信する必要がある場合 (たとえば、clientと呼ばれる実行可能ファイルとserverと呼ばれる実行可能ファイルがある場合)、このメカニズムを使用することはできません。代わりに、次のことができます。

  • UNIX ソケットを使用します (1 つのホスト上の IPC パイプはファイル名で識別されます。これは、クライアントサーバーが同じマシンで実行されている場合にのみ機能します)。
  • またはTCP / IPソケットを使用します(IPアドレスとポートがパイプを識別し、クライアントサーバーが異なるマシン上にある場合があります)

特にソケットが必要なく、クライアントサーバーを同じマシンで実行する必要がある場合は、共有メモリまたはメッセージ キューを使用することもできます。

于 2012-07-12T21:54:56.190 に答える
8

socketpair匿名のソケットのペア (通常は unix/ローカル ソケット) を作成します。これは、親プロセスと子プロセスの間の通信、またはそれらを使用する必要があるプロセスが共通の祖先からファイル記述子を継承できる場合にのみ役立ちます。

関係のない (親子関係という意味で) プロセス間で通信を行う場合はsocket、 、bind、およびを使用connectして、一方のプロセスでリッスン ソケットを作成し、もう一方のプロセスでそれに接続するクライアント ソケットを作成する必要があります。

于 2012-07-12T21:47:41.060 に答える
1

2 つのプロセス間の通信については、はい、プロセス間通信または IPC を探す必要があります。ソケットは通信方法の 1 つにすぎず、1 対多接続を実装する必要がある場合に役立ちます。つまり、1 つのサーバー プロセスが多くのクライアント プロセスと要求応答方式で通信します。あなたが IPC の初心者であるため、ソケット アドレスと関連する詳細を把握するのが難しいように見えることは理解できます。(ただし、やがて簡単になるでしょう:-))

あなたの問題については、パイプ、FIFO、メッセージ キューなどのより単純な IPC メカニズムを使用することをお勧めします。socketpair を使用するという結論に至った経緯がわかりません。必要な IPC の設計や種類については何も言及されておらず、使用レベルに基づいているため、本やインターネットでパイプまたは FIFO のサンプル コードを調べることを強くお勧めします。それらはソケットよりも実装がはるかに簡単で、高速に動作するように見えるはずです。

于 2012-07-14T19:25:45.157 に答える
-3

TCP/IP を使用します。他の IPC メカニズム (Unix ドメイン ソケットや SYSV IPC など) も利用できますが、多くの理由から TCP/IP を使用する方が適切です。ここにあるいくつかの:

  1. TCP/IP の実行方法を説明するチュートリアルやその他の情報がウェブ上にたくさんあります。
  2. 最新のシステム、特に Linux と *BSD では、たとえば Unix ドメイン ソケットや SYSV IPC と比較して、TCP/IP の使用に重大なペナルティを課すことはありません。
  3. TCP/IP を介して通信するアプリケーションに利用できるライブラリとフレームワークが多数あります。

2 つの「プログラム」間の通信に TCP/IP を使用しない唯一のケースは、それらが別個のプログラムではなく、実際にはスレッドである場合です。

于 2012-07-12T21:48:40.023 に答える