Первое решение, использующее чтение / запись для обмена любым количеством сообщений
Здесь я указываю конец каждого буфера для чтения с помощью \ n:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
void rd(int fd, int child)
{
char c;
int first = 1;
do {
if (!read(fd, &c, 1))
break;
if (first) {
printf("%s got:", (child) ? "Child" : "Parent");
first = 0;
}
putchar(c);
} while (c != '\n');
}
void wr(int fd, const char * msg, int child)
{
write(fd, msg, strlen(msg));
printf("%s sent:%s", (child) ? "Child" : "Parent", msg);
}
int main() {
int child_to_parent[2];
int parent_to_child[2];
pipe(child_to_parent);
pipe(parent_to_child);
pid_t id = fork();
if (id == 0) {
close(parent_to_child[1]);
close(child_to_parent[0]);
rd(parent_to_child[0], 1);
wr(child_to_parent[1], "hi\n", 1);
rd(parent_to_child[0], 1);
wr(child_to_parent[1], "fine, and you ?\n", 1);
rd(parent_to_child[0], 1);
} else {
close(parent_to_child[0]);
close(child_to_parent[1]);
wr(parent_to_child[1], "hello\n", 0);
rd(child_to_parent[0], 0);
wr(parent_to_child[1], "how are you ?\n", 0);
rd(child_to_parent[0], 0);
wr(parent_to_child[1], "fine too\n", 0);
}
}
Компиляция и выполнение:
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra p.c
pi@raspberrypi:/tmp $ ./a.out
Parent sent:hello
Child got:hello
Child sent:hi
Parent got:hi
Parent sent:how are you ?
Child got:how are you ?
Child sent:fine, and you ?
Parent got:fine, and you ?
Parent sent:fine too
Child got:fine too
Можно также использовать fread / fwrite , fflush необходимо после fwrite , чтобы не блокировать.К счастью, нет необходимости закрывать канал после отправки, чтобы иметь возможность читать и отвечать, иначе можно обменяться только одним сообщением.Я по-прежнему использую \ n, чтобы указать конец отправленного буфера:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
void rd(FILE * fd, int child)
{
char c;
int first = 1;
do {
if (!fread(&c, 1, 1, fd))
break;
if (first) {
printf("%s got:", (child) ? "Child" : "Parent");
first = 0;
}
putchar(c);
} while (c != '\n');
}
void wr(FILE * fd, const char * msg, int child)
{
fwrite(msg, strlen(msg), 1, fd);
fflush(fd);
printf("%s sent:%s", (child) ? "Child" : "Parent", msg);
}
int main() {
int child_to_parent[2];
int parent_to_child[2];
pipe(child_to_parent);
pipe(parent_to_child);
pid_t id = fork();
if (id == 0) {
close(parent_to_child[1]);
close(child_to_parent[0]);
FILE* out = fdopen(child_to_parent[1], "w");
FILE* in = fdopen(parent_to_child[0], "r");
rd(in, 1);
wr(out, "hi\n", 1);
rd(in, 1);
wr(out, "fine, and you ?\n", 1);
rd(in, 1);
} else {
close(parent_to_child[0]);
close(child_to_parent[1]);
FILE* in = fdopen(child_to_parent[0], "r");
FILE* out = fdopen(parent_to_child[1], "w");
wr(out, "hello\n", 0);
rd(in, 0);
wr(out, "how are you ?\n", 0);
rd(in, 0);
wr(out, "fine too\n", 0);
}
}
Компиляция и выполнение:
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra pp.c
pi@raspberrypi:/tmp $ ./a.out
Parent sent:hello
Child got:hello
Child sent:hi
Parent got:hi
Parent sent:how are you ?
Child got:how are you ?
Child sent:fine, and you ?
Parent got:fine, and you ?
Parent sent:fine too
Child got:fine too
И, наконец, если вы хотите использовать fscanf("%s", ...)
вам нужно послать разделитель (например, пробел или \ n) после слова, чтобы не блокировать fscanf и, конечно, также прочитать символ разделителя , fflush необходим после fwrite .
Если я немного изменю вашу программу:
#include <stdio.h>
#include <unistd.h>
int main() {
int child_to_parent[2];
int parent_to_child[2];
pipe(child_to_parent);
pipe(parent_to_child);
pid_t id = fork();
if (id == 0) {
close(parent_to_child[1]);
close(child_to_parent[0]);
FILE* out = fdopen(child_to_parent[1], "w");
FILE* in = fdopen(parent_to_child[0], "r");
char msg[16], c;
fscanf(in ,"%s%c", msg, &c);
printf("Child got: %s\n", msg);
fprintf(out, "hi ");
fflush(out);
printf("Child sent: hi\n");
fscanf(in ,"%s%c", msg, &c);
printf("Child got: %s\n", msg);
fprintf(out, "fine,you? ");
fflush(out);
printf("Child sent: fine,you?\n");
fscanf(in ,"%s%c", msg, &c);
printf("Child got: %s\n", msg);
} else {
close(parent_to_child[0]);
close(child_to_parent[1]);
FILE* in = fdopen(child_to_parent[0], "r");
FILE* out = fdopen(parent_to_child[1], "w");
fprintf(out, "hello\n");
fflush(out);
printf("Parent sent: hello\n");
char msg[16], c;
fscanf(in, "%s%c", msg, &c);
printf("Parent got: %s\n", msg);
fprintf(out, "how-are-you? ");
fflush(out);
printf("Parent sent: how-are-you?\n");
fscanf(in, "%s%c", msg, &c);
printf("Parent got: %s\n", msg);
fprintf(out, "fine-too ");
fflush(out);
printf("Parent sent: fine-too\n");
}
}
Компиляция и выполнение:
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra ppp.c
pi@raspberrypi:/tmp $ ./a.out
Parent sent: hello
Child got: hello
Child sent: hi
Parent got: hi
Parent sent: how-are-you?
Child got: how-are-you?
Child sent: fine,you?
Parent got: fine,you?
Parent sent: fine-too
Child got: fine-too