Reputation: 121
My server and client are communicating back and forth using two named pipes (fifo) in C until the server receives an exit
message.
Apparently the server side blocks the second time it tries to read()
from its FIFO despite the client writing to it successfully. I think the problem is that the server tries to read()
sooner than the client could write()
to it.
Here is the server:
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "header.h"
#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>
int main(int argc, char *argv[]) {
//fifo for the server to read from
if (mkfifo(FIFONAME, S_IFIFO|0666) < 0) {
if (errno != EEXIST) {
perror("Error with mkfifo");
exit(1);
}
}
int f;
if ((f = open(FIFONAME, O_RDONLY)) < 0) {
perror("Error with open");
exit(1);
}
Message msg;
while(1) {
if ((read(f, &msg, sizeof(Message))) > 0) {
if (strcmp(msg.user, "exit") == 0) {
close(f);
unlink(FIFONAME);
exit(0);
}
if (strcmp(msg.user, "new client") == 0) {
switch (fork()) {
case -1:{
perror("Error with fork");
exit(1);
}
case 0:{
char gender[MAXLEN];
char client_fifo[30];
sprintf(msg.user, "I need client's gender\n");
sprintf(client_fifo, "fifo_%d", msg.pid);
msg.pid = getpid();
int o;
//open client's fifo for server to write to
if ((o = open(client_fifo, O_WRONLY)) == -1) {
perror("Error opening client fifo");
exit(1);
}
//send message
write(o, &msg, sizeof(Message));
//read client's answer, but program blocks here
if ((read(f, &msg, sizeof(Message))) > 0) {
sprintf(gender,"%s", msg.user);
printf("Client's gender is %s\n", gender);
}
close(o);
exit(0);
}
}
}
}
}
return 0;
}
The client code:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "header.h"
#include <unistd.h>
int f,fc;
char fifoname[20];
Message msg;
int main(int argc, char* argv[]) {
sprintf(fifoname, "fifo_%d", getpid());
if (mkfifo(fifoname, S_IFIFO | 0666) < 0) {
perror("Error with client's fifo");
printf("Could not create fifo_%d", getpid());
exit(1);
}
if ((f=open(FIFONAME,O_WRONLY))<0) {
perror("Error connecting to server");
exit(2);
}
char gender[MAXLEN];
strcpy(msg.user, "new client");
msg.pid = getpid();
//first message to server
write(f, &msg, sizeof(msg));
char arg[MAXLEN];
if (argc > 1) {
strcpy(arg, argv[1]);
} else {
strcpy(arg, "work");
}
if (strcmp(arg, "exit")) {
if ((fc = open(fifoname, O_RDONLY))<0) {
perror("Error opening client's fifo");
printf("Could not open my fifo");
exit(3);
}
if (read(fc, &msg, sizeof(msg)) > 0) {
printf("%s\n",msg.user);
}
scanf("%s", gender);
strcpy(msg.user, gender);
msg.pid = getpid();
printf("writing gender...\n");
write(f, &msg, sizeof(msg));
//program successfully reaches this print:
printf("gender written\n");
close(fc);
}
unlink(fifoname);
close(f);
exit(0);
}
And the header containing the struct for the message:
#define MAXLEN 20
typedef struct {
int pid;
char user[MAXLEN];
} Message;
#define FIFONAME "fifo_server"
I need to write further back and forth messages like this but I don't know how to get the server not to block on the second call of read()
Upvotes: 0
Views: 167