Именованные каналы на самом деле не идеальны для этого - они лучше всего подходят для ситуаций с одним читателем и с одним автором.
Сокеты UNIX-домена, однако, идеально подходят для этого. Они используют API сокетов с именем конечной точки, являющимся записью файловой системы (как с именованным каналом).
Вот очень простой пример (вы, конечно, захотите добавить обильную проверку ошибок!). Сначала на стороне сервера:
#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;
}
Теперь на стороне клиента:
#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;
}
Обратите внимание, что на самом деле вы должны создавать сокет в /var/run/yourappname
, а не в /tmp
.
man 7 unix
- хороший ресурс для дальнейшего изучения.