Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can use <code>socketpair</code> only where you create both processes, like so:</p> <ol> <li>call <code>socketpair</code> - now you have two socket file descriptors (two ends of a single pipe) <ul> <li>nominate one end to be the <em>parent</em> and one to be the <em>child</em> end. It doesn't matter which, just make a choice and stick to it later</li> </ul></li> <li>call <code>fork</code> - now you have two processes <ol> <li>if <code>fork</code> returned zero, you are the child. Close the <em>parent</em> file descriptor, keep the <em>child</em> descriptor, and use it as this process's end of the pipe</li> <li>if <code>fork</code> returned non-zero, you are the parent. Close the <em>child</em> file descriptor, keep the <em>parent</em> one and use it as your end of the pipe</li> </ol></li> <li>you now have two processes, each has one file descriptor representing different ends of the same pipe. Note that both processes are running the same program, but they followed a different branch after calling <code>fork</code>. If <em>parent</em> calls <code>write</code> on its socket, <em>child</em> will be able to read that data from <em>its</em> socket, and vice-versa</li> </ol> <p>Here is a straight translation into code:</p> <pre><code>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 */ } </code></pre> <p>Please note that this is just sample code: I've left out all error-checking and a sensible stream protocol.</p> <hr> <p>If you want two <em>separate</em> programs to communicate (eg. you have an executable called <em>client</em>, and one called <em>server</em>), you can't use this mechanism. Instead, you might:</p> <ul> <li>use UNIX sockets (where an IPC pipe on one host is identified by a filename - this only works if <em>client</em> and <em>server</em> run on the same machine)</li> <li>or use TCP/IP sockets (where an IP address and port identify the pipe, and the <em>client</em> and <em>server</em> can be on different machines)</li> </ul> <hr> <p>If you don't <em>specifically</em> need sockets, and you're happy to require that <em>client</em> and <em>server</em> run on the same machine, you can also use shared memory, or message queues.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload