I have 2 applications on the same system that I need to communicate back and forth. From my research I believe this is called Inter Process Communication and the use of socketpair() is the best method for my problem.
I am tearing my hair out (literally) trying to get started with creating sockets with socketpair() in C. From what I understand, sockets are a very complex topic and me being a novice C programmer is surely not helping the situation.
I googled for the last 48 hours, read tutorials, etc, but I still can't get it. I understand the concept, but the code is just too confusing. I've read this article a few times: http://beej.us/guide/bgnet/html/single/bgnet.html, but it's not simple enough.
Can someone provide some example (so simple a 5th grader could understand) or point me to a good tutorial?
The socketpair() function shall create an unbound pair of connected sockets in a specified domain, of a specified type, under the protocol optionally specified by the protocol argument.
The AF_UNIX (also known as AF_LOCAL) socket family is used to communicate between processes on the same machine efficiently. Traditionally, UNIX domain sockets can be either unnamed, or bound to a filesystem pathname (marked as being of type socket).
AF_LOCAL uses UNIX domain sockets which are local to the filesystem and can be used for internal communications. AF_INET is an IP socket. AF_LOCAL will not incur some performance penalties related to sending data over IP.
The socket pair is a full-duplex communications channel, so that both reading and writing may be performed at either end. The namespace , style and protocol arguments are interpreted as for the socket function. style should be one of the communication styles listed in Communication Styles.
You can use socketpair
only where you create both processes, like so:
socketpair
- now you have two socket file descriptors (two ends of a single pipe) fork
- now you have two processes fork
returned zero, you are the child. Close the parent file descriptor, keep the child descriptor, and use it as this process's end of the pipefork
returned non-zero, you are the parent. Close the child file descriptor, keep the parent one and use it as your end of the pipefork
. If parent calls write
on its socket, child will be able to read that data from its socket, and vice-versaHere is a straight translation into 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 */ }
Please note that this is just sample code: I've left out all error-checking and a sensible stream protocol.
If you want two separate programs to communicate (eg. you have an executable called client, and one called server), you can't use this mechanism. Instead, you might:
If you don't specifically need sockets, and you're happy to require that client and server run on the same machine, you can also use shared memory, or message queues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With