Reputation: 24964
For my application, I need to have a central process responsible for interacting with many client processes. The client processes need a way to identify and communicate with the central process. Additionally, the central process may not be running, and the client process needs a way to identify that fact. This application will be running on a Unix-like system, so I'd thought about using named pipes sockets for the task. How would I, specifically, go about using named pipes sockets for this task (actual code would be greatly appreciated!)? If named pipes sockets are not ideal, are there better alternatives?
Upvotes: 4
Views: 1758
Reputation: 239041
Named pipes are not really ideal for this - they are best suited for single-reader, single-writer situations.
UNIX-domain sockets, however, are perfectly suited for it. They use the sockets API, with the endpoint name being a filesystem entry (as with a named pipe).
Here's a very simple example (you will of course want to add copious error checking!). First the server side:
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#define SOCKNAME "/tmp/foo"
int main()
{
int s1, s2;
int i;
struct sockaddr_un sa = { AF_UNIX, SOCKNAME };
unlink(SOCKNAME);
s1 = socket(AF_UNIX, SOCK_STREAM, 0);
bind(s1, (struct sockaddr *)&sa, sizeof sa);
listen(s1, 5);
for (i = 0; i < 10; i++)
{
struct sockaddr_un sa_client;
socklen_t sa_len = sizeof sa_client;
FILE *f;
s2 = accept(s1, (struct sockaddr *)&sa_client, &sa_len);
f = fdopen(s2, "r+");
fprintf(f, "Hello, you are client number %d\n", i + 1);
fclose(f);
}
return 0;
}
Now the client side:
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCKNAME "/tmp/foo"
int main()
{
int s1;
struct sockaddr_un sa = { AF_UNIX, SOCKNAME };
FILE *f;
char buffer[1024];
s1 = socket(AF_UNIX, SOCK_STREAM, 0);
connect(s1, (struct sockaddr *)&sa, sizeof sa);
f = fdopen(s1, "r+");
while (fgets(buffer, sizeof buffer, f) != NULL)
{
printf("Message received: %s", buffer);
}
fclose(f);
return 0;
}
Note that you should actually create the socket under /var/run/yourappname
rather than in /tmp
.
man 7 unix
is a good resource for further investigation.
Upvotes: 7
Reputation: 40558
Based on the info in your question it sounds like you are building a distributed system which has a central message passing bus which components use for communications. I would recommend TCP sockets for the following reasons:
Upvotes: 0
Reputation: 753735
You need to read one of the standard text books on the subject - probably Stevens 'UNIX Network Programming, Vol 1, 3rd Edn'.
You have to make a number of decisions, including:
These decisions radically impact the code that's required. If the process is dealing with one short message at a time, it might be appropriate to consider UDP instead of TCP. If the process is dealing with extended conversations with several correspondents and is not forking a child to handle them, then you can consider whether threaded programming is appropriate. If not, you need to consider timeliness and whether the central process can be held up indefinitely.
As indicated in a comment, you also need to consider how a process should deal with the central process not running - and you need to consider how fast that response should be. You also have to protect against the central process being so busy that it looks like it is not running, even though it is running but is just very busy dealing with other connections. How much trouble do you get into if the process that can't connect to the central process tries to kick off a new copy of it.
Upvotes: 0
Reputation: 798666
D-Bus provides object-oriented IPC, plus includes an activation feature which will start up the server process if it is not already running. The downside is that network encapsulation is basically DIY.
Upvotes: 0
Reputation: 35117
Is this an application that already makes use of a database? If so I would use that rather than adding another whole communication medium to the mix.
Upvotes: 0