I used a simple fork() to simulate client / server then a very simple pipe to send / receive a char buffer of max 30 length, but it ends up printing non printable characters (small “?” and a box with 4 ones and zeroes) AFTER the desired word.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
int main () {
int pipefd[2];
int cpid;
char buf[31];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE)
}
cpid = fork();
if (cpid == -1) P
perror("cpid");
exit(EXIT_FAILURE);
}
if (cpid == 0) { // child reads from pipe
close (pipefd[1]); // close unused write end
read (pipefd[0], &buf, 30); // if I use 30 instead of strlen(buf) it prints Server transmit: Server receives. It does not wait for write. Makes no sense
printf ("Server receives: %s", buf);
close (pipefd[0])l
exit (EXIT_SUCCESS);
}
else { // parent writes to pipe
close (pipefd[0]); // closing unused read end;
char buf2[30];
printf("Server transmits: ");
scanf ("%s", buf2);
write (pipefd[1], buf2, strlen(buf2));
close(pipefd[1]);
wait(NULL);
exit(EXIT_SUCCESS);
}
return 0;
}
Also if I write more than one word it forgets about the second. In c++ I used getline (cin, string) but that’s not an option here.
Also used read (pipefd[0], &buf, sizeof(buf));, now it prints in the correct order (no idea why strlen did not work) but I still get non printable characters at the end.
When you
write (pipefd[1], buf2, strlen(buf2));You neglect to put the'\0'in the stream. Change that to:And your string will now contain the null terminator, preventing the garbage at the end.
Using
read (pipefd[0], &buf, strlen(buf))did not work becausebufis uninitialized.strlenis a simple function which looks for the terminating null at the end on the string, stopping when it’s found. Unlike thelengthfunctions of C++ vectors, C functions have no way of accessing memory metadata. (sizeofis an operator)