Need Help in Client and Server Programming in C - c

I am coding a small C program to test the client and server programs so that the client sends an integer to the client. The server multiplies the number by 10 and returns the integer*10 back to the client. When writing the integers to the FIFO, use sizeof(int) as the number of bytes in the 3rd parameter of the write( ) and read( ).
That is my code so far:
The Client task:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
main (void)
{
int fda; // to write to server
int fdb; // to read response from server
int number;
int outputnumber;
if((fda=open("FIFO_to_server", O_WRONLY))<0)
printf("cant open fifo to write");
if((fdb=open("FIFO_to_client", O_RDONLY))<0)
printf("cant open fifo to read");
printf("Client: Please enter an integer: ");
scanf("%d", &number);
write(fda, &number, sizeof(number));
printf("\nClient: Got the number sent, now waiting for response ");
read(fdb, &outputnumber, sizeof(outp utnumber));
printf("\nClient: received from server %s", outputnumber);
close(fda);
close(fdb);
printf ("\nall done!\n");
}
The server task:
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
main (void)
{
int fda; // to read from client
int fdb; // to write to client
int finish; // lets me know that client is done
int number;
int outputnumber;
/* Create the fifos and open them */
if ((mkfifo("FIFO_to_server",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO_to_server");
exit(-1);
}
if ((mkfifo("FIFO_to_client",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO_to_client");
exit(-1);
}
if((fda=open("FIFO_to_server", O_RDONLY))<0)
printf("cant open fifo to write");
if((fdb=open("FIFO_to_client", O_WRONLY))<0)
printf("cant open fifo to read");
finish=read(fda, number, sizeof(number)); //read the character
printf("Server: just got the number: ,%d", number));
outputnumber = 10*number;
write(fdb, outputnumber,sizeof(outputnumber));
printf("\nServer: Got the number sent");
if(finish == 1)
printf("\nServer: This says I am ready to close ");
close(fda);
close(fdb);
unlink("FIFO_to_server");
unlink("FIFO_to_client");
}
The Client's output show error:
-bash-3.2$ ./client
Client: Please enter an integer: 10
Client: Got the number sent, now waiting for response
Client: received from server ▒+▒▒▒▒▒▒7▒▒x}
all done!
The Server:
-bash-3.2$ ./server
Server: just got the number: 134614968
Server: Got the number sent-bash-3.2$

Related

How to get multiple strings from pointer that stores the output of a shell script in C?

I am trying to write a code in C with named pipes (fifo), where the client is asking for information about a directory.
The server checks for the existence of the directory, and sends back the size of the directory, and the number of files and subdirectories.
The request can also specify to get the name of the files and subdirectories.
The client gets the name of the directory as an argument, also the specification by -d option.
The server executes a shell script in order to solve the problem.
I already asked a question about this topic and got some improvements in the code, but still can't get it running correctly.
Here is the link to the question: How to pass multiple arguments to client (fifo)?
My problem is now that the server prints out only one file name instead of all filenames and subdirectories inside the directory that was given as an argument to the client.
Here is the modified server code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "header.h"
int f;
Message msg;
int main() {
if (mkfifo(FIFONAME, S_IFIFO | 0666) < 0) { /*Creating server fifo*/
perror("Failed creating own fifo");
printf("Server: Failed creating fifo_%d file\n", getpid());
unlink(FIFONAME);
exit(1);
}
if ((f = open(FIFONAME, O_RDONLY)) < 0) {
perror("Failed opening fifo");
unlink(FIFONAME);
exit(1);
}
printf("Server is working\n");
while (1) { /*Infinite loop, waiting for client requests*/
if ((read(f, &msg, sizeof(msg)))) {
if (strcmp(msg.dir, "exit") == 0) {
close(f);
unlink(FIFONAME);
exit(1);
}
switch (fork()) {
case -1: {
perror("Fork error\n");
exit(1);
}
case 0: {
char command[MAXLEN];
sprintf(command,"./shell.sh %s %s", msg.dir, msg.spec);
FILE *g;
if ((g = popen(command, "r")) == NULL) {
perror("Popen error");
exit(1);
}
fgets(msg.dir, MAXLEN, g);
fgets(msg.spec, MAXLEN, g);
char result[MAXLEN];
sprintf(result, "fifo_%d", msg.pid);
msg.pid = getpid();
int op;
op = open(result, O_WRONLY);
write(op, &msg, sizeof(msg));
close(op);
exit(0);
}
}
}
}
return 0;
}
And the client code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "header.h"
int f, fc;
Message msg;
char fifoname[MAXLEN];
int main(int argc, char *argv[]) {
if (argc == 1) {
printf("Usage: %s directory name\n",argv[0]);
exit(1);
}
sprintf(fifoname, "fifo_%d", getpid());
if (strcmp(argv[1], "0"))
if (mkfifo(fifoname, S_IFIFO | 0666) < 0) { /*Creating own FIFO file for result*/
perror("Failed creating own clientfifo");
printf("Client error: Failed creating fifo_%d file\n", getpid());
exit(2);
}
if ((f = open(FIFONAME, O_WRONLY)) < 0) { /*Opening serverfifo for writing*/
perror("Failed connecting to server");
exit(3);
}
strcpy(msg.dir, argv[1]);
strcpy(msg.spec, argv[2]);
msg.pid = getpid();
write(f, &msg, sizeof(msg));
if (strcmp(argv[1], "exit")) { /* The client is not expecting any result
because the server stopped*/
if ((fc = open(fifoname, O_RDONLY)) < 0) { /*Opening own fifo for reading*/
perror("Failed opening own fifo");
printf("Client error: Failed opening own %s file\n", fifoname);
exit(4);
}
read(fc, &msg, sizeof(msg));
printf("Client %d, received: %s%s\n", getpid(), msg.dir, msg.spec);
close(fc);
}
unlink(fifoname);
close(f);
exit(0);
}
The common header file:
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#define FIFONAME "server_fifo"
#define MAXLEN 1000
typedef struct {
int pid; /*folyamat azonositoja*/
char dir[MAXLEN];
char spec[MAXLEN];
} Message;
And the output I get is:
-bash-4.1$ ./client dir -d
Client 42723, received: 16K,2 directories, 2 files
a
While it should look like this :
-bash-4.1$ ./client dir -d
Client 42723, received: 16K,2 directories, 2 files
a
b
dir1
dir2
What needs to be modified in order to get the full output?
The problem is at line 52 inside server.c.
You are using fgets() to copy the output to msg.spec.
But fgets() stops taking input at newline charater ('\n').
Hence you only see one result.
To overcome this, you can do something like:
char str[100]; // arbitrary length
while(fgets(str, MAXLEN, g))
{
strcat(msg.spec, str);
}
This keeps taking input every iteration and concatenates each line to previous output.

Sending a process id from client to server

My task is to write a client program that writes a struct with a privateFIFO name (FIFO_XXXX, where XXXX is the pid that we get from the getpid( ) function) to the server. Then, have the server read the privateFIFO name and write a message back to the client. i.e., Read the message and print it on the client side. I am having trouble sending the FIFO_XXXX to the server program and also writing a message from the server back to client.
client code:
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main (void)
{
struct values
{
char privateFIFO[14];
int intbuff;
}input;
int fda; // common FIFO to read to write to server
int fdb; // Private FIFO to read from server
int clientID;
int retbuff;
char temp[14];
clientID = getpid();
strcpy(input.privateFIFO, "FIFO_");
sprintf(temp, "%d", clientID);
strcat(input.privateFIFO, temp);
printf("\nFIFO name is %s", input.privateFIFO);
// Open common FIFO to write to server
if((fda=open("FIFO_to_server", O_WRONLY))<0)
printf("cant open fifo to write");
write(fda, &input, sizeof(input)); // write the struct to the server
close(fda);
// Open private FIFO to read
if((fdb=open(input.privateFIFO, O_RDONLY))<0)
read(fdb, &retbuff, sizeof(retbuff));
printf("\nAll done!\n");
close(fdb);
}
server code:
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
struct values
{
char privateFIFO[14];
int intbuff;
}input;
int main (void)
{
int fda; //common FIFO to read from client
int fdb; //private FIFO to write to client
int retbuff;
int output;
// create the common FIFO
if ((mkfifo("FIFO_to_server",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO_to_server");
exit(-1);
}
// open the common FIFO
if((fda=open("FIFO_to_server", O_RDONLY))<0)
printf("cant open fifo to write");
output = read(fda, &input, sizeof(input));
// create the private FIFO
if ((mkfifo(input.privateFIFO, 0666)<0 && errno != EEXIST))
{
perror("cant create privateFIFO_to_server");
exit(-1);
}
printf("Private FIFO received from the client and sent back from server is: %d", output);
//open private FIFO to write to client
if((fdb=open(input.privateFIFO, O_WRONLY))<0)
printf("cant open fifo to read");
write(fdb, &retbuff, sizeof(retbuff));
close(fda);
unlink("FIFO_to_server");
close(fdb);
unlink(input.privateFIFO);
}
Use IPC message Queues. It better and simple. Indeed, This mechanism manages synchronization between read and write operations, concurrent access, ...:
The Writer Process:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
// structure for message queue
struct mesg_buffer {
long mesg_type;
char mesg_text[100];
} message;
int main()
{
key_t QueueKey;
int msgid;
// ftok : generate a unique OPC key
QueueKey = ftok("FIFO_XXXX", 65);
// msgget creates a message queue and returns identifier
msgid = msgget(QueueKey, 0666 | IPC_CREAT);
// Sending Data
message.mesg_type = 1;
printf("Write Data : ");
gets(message.mesg_text);
// msgsnd : Send message to the queue
msgsnd(msgid, &message, sizeof(message), 0);
// display the message
printf("Data send is : %s \n", message.mesg_text);
return 0;
}
The Reader Process:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
// structure for message queue
struct mesg_buffer {
long mesg_type;
char mesg_text[100];
} message;
int main()
{
key_t QueueKey;
int msgid;
// ftok to generate unique key
QueueKey = ftok("FIFO_XXXX", 65);
// msgget creates a message queue and returns identifier
msgid = msgget(QueueKey, 0666 | IPC_CREAT);
// msgrcv to receive message
msgrcv(msgid, &message, sizeof(message), 1, 0);
// display the message
printf("Data Received is : %s \n", message.mesg_text);
// IPC_RMID : destroy the message queue
msgctl(msgid, IPC_RMID, NULL);
return 0;
}
Remarque:
Be aware that a process can be both writer and reader. To do this, two message queues must be created for each process. the first allows for example to receive, the second to write. If you really want to separate read / write spaces for each process.

How to send line of text from server to client in C?

This program, on the server side, asks the user for an array size, array elements and an integer value to be searched in the array. If found it prints a message such as "The value 87 occurs at index position 4" and sends it back to client. I have managed to come up with the following code for server and client. However, how do I send the result of the search such as "The value 87 occurs at index position 4" back to server from client?
Client Code:
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#define MAX_SIZE 10 //maximum array size
int main (void)
{
int fda; // to write to server
int fdb; // to read response from server
struct{
int size;
int i;
int arr[MAX_SIZE];
} input;
if((fda=open("FIFO_to_server", O_WRONLY))<0)
printf("cant open fifo to write");
printf("Client: Please enter size of the array: ");
scanf("%d", &input.size);
printf("Enter the elements of the array: ");
for(i=0; i<size; i++)
{
scanf(%d", &arr[i]);
}
write(fda, &input, sizeof(input));
close(fda);
printf("\nClient: Got the array sent, now waiting for response ");
if((fdb=open("FIFO_to_client", O_RDONLY))<0)
printf("cant open fifo to read");
close(fdb);
printf ("\nall done!\n");
}
Server Code
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/types.h>
int main (void)
{
int fda; // to read from client
int fdb; // to write
int i;
int toSearch;
int found;
int finish;
/* Create the fifos and open them */
if ((mkfifo("FIFO_to_server",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO_to_server");
exit(-1);
}
if ((mkfifo("FIFO_to_client",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO_to_client");
exit(-1);
}
if((fda=open("FIFO_to_server", O_RDONLY))<0)
printf("cant open fifo to write");
if((fdb=open("FIFO_to_client", O_WRONLY))<0)
printf("cant open file to read");
finish=read(fda, &input, sizeof(input));
printf("Server: just got the array: %d", arr);
printf("\Enter the integer to be searched in the array: ");
found = 0;
for(i=0; i<size; i++)
{
if(arr[i] == toSearch)
{
found = 1;
break;
}
}
if(found == 1)
{
printf("\n%d is found at position %d", toSearch, i + 1);
}
else
{
printf("\n%d is not found in the array", toSearch);
}
return 0;
close(fdb);
unlink("FIFO_to_client");
close(fda);
unlink("FIFO_to_server");
}

C language, using structs to send data from client to server

I have to create a client and server, where the client will send a character and an integer (using structs) and then my client will iterate the letter by n (integer) times and will send it back to the client.
For instance: a and 4 are sent from the client, server will manipulate and send a string of 4 a's (aaaa) back to the client.
I know I am really close to get the code but once I send my char and int, I get a "segmentation fault (core dumped) error". I have done my research and the error shows up due to a missing cast, memory being accessed where is not supposed to access, or that a pointer might be null.
The code is as follow:
Client:
// ClientTest.c
// opens fifo1 for writing and fifo2 for reading
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
struct problem {
char letter[1];
int number[1];
};
main (void)
{
struct problem x=0; //Initializing structure to null
int fda; // to write to character server
int fdb; // to read response from character server
int i; // for the iteration
printf("Client: Please enter a character: ");
scanf("%c", &x.letter[0]);
printf("Client: Please enter an integer: ");
scanf("%d", &x.number[0]);
memset(&x.letter, 0, 1);
memset(&x.number, 0, 1);
if((fda=open("FIFO1", O_WRONLY))<0)//opening and validating fifos
printf("cant open fifo to write");
if((fdb=open("FIFO2", O_RDONLY))<0)
printf("cant open fifo to read");
write(fda, x.number, 1);
printf("\nClient: Got the integer sent, now waiting for response ");
//sleep(0.250);
write(fda, x.letter, 1);
printf("\nClient: Got the character sent, now waiting for response ");
char outletter[7];
read(fdb, outletter, 7);
printf("\nClient: received characters from server %c", outletter);
close(fda);
close(fdb);
printf ("\nall done!\n");
}
server
// ServerTest.c
// makes 2 fifos named fifo1 and fifo2
// opens fifo1 for reading and fifo2 for writing
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
struct problem {
char letter[1]; // struct to store the character
int number [1]; // struct to store the integer
};
main (void)
{
struct problem x;
int fda; // to read from client char
int fdb; // to write to client char
int finish; // lets me know that client is done
int i; // because C needs this defined as int
int p;
char outletter[7];
memset(&x.letter, 0, 7);
memset(&x.number, 0, 1);
/* Create the fifos and open them */
if ((mkfifo("FIFO1",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO1");
exit(-1);
}
if ((mkfifo("FIFO2",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO2");
exit(-1);
}
if((fda=open("FIFO1", O_RDONLY))<0)
printf("cant open fifo to write");
if((fdb=open("FIFO2", O_WRONLY))<0)
printf("cant open fifo to read");
read(fda, x.letter, 1); //read the character
read(fda, x.number, 1); //read the integer
printf("\nServer: just got character: , %c", x.letter[0]);
printf("\nServer: just got integer: , %d", x.number[0]);
p=x.number[0]-'0';
for( i = 0; i<=p; i++) // iteration to create the character's string
outletter[p] = x.letter[0];
printf("iteration: %d and character: %c\n", i, outletter[0]); // validating the character and integer received
printf("\nServer: outchar is, %s", outletter); // this shows the character to be sent back to client
write(fdb, outletter, p);
printf("\nServer: Got the characters sent: %s", outletter ); // this sends the letter back to client
if(finish == 1)
printf("\nServer: This says I am ready to close ");
close(fda);
close(fdb);
unlink("FIFO1");
unlink("FIFO2");
}
There are many problems with your code, I've made it running but you can still improve it.
Client:
// ClientTest.c
// opens fifo1 for writing and fifo2 for reading
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
struct problem {
char letter[1];
int number[1];
};
main (void)
{
struct problem x;
int fda; // to write to character server
int fdb; // to read response from character server
int i; // for the iteration
memset(&x, 0, sizeof(struct problem)) ;
printf("Client: Please enter a character: ");
scanf("%c", x.letter);
printf("Client: Please enter an integer: ");
scanf("%d", x.number);
// removed or else the letter and number would be reverted to zero
// memset(&x.letter, 0, sizeof(char));
// memset(&x.number, 0, sizeof(int));
if((fda=open("FIFO1", O_WRONLY))<0)//opening and validating fifos
printf("cant open fifo to write");
if((fdb=open("FIFO2", O_RDONLY))<0)
printf("cant open fifo to read");
write(fda, x.letter, sizeof(char));
printf("\nClient: Got the character sent, now waiting for response ");
write(fda, x.number, sizeof(int));
printf("\nClient: Got the integer sent, now waiting for response ");
//sleep(0.250);
char outletter[7];
read(fdb, outletter, 7);
printf("\nClient: received characters from server:") ;
printf("%s\n", outletter);
close(fda);
close(fdb);
printf ("\nall done!\n");
}
Server:
// ServerTest.c
// makes 2 fifos named fifo1 and fifo2
// opens fifo1 for reading and fifo2 for writing
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
struct problem {
char letter[1]; // struct to store the character
int number[1]; // struct to store the integer
};
main (void)
{
struct problem x;
int fda; // to read from client char
int fdb; // to write to client char
int finish; // lets me know that client is done
int i; // because C needs this defined as int
int p;
char outletter[7];
memset(x.letter, 0, sizeof(char));
memset(x.number, 0, sizeof(int));
/* Create the fifos and open them */
if ((mkfifo("FIFO1",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO1");
exit(-1);
}
if ((mkfifo("FIFO2",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO2");
exit(-1);
}
if((fda=open("FIFO1", O_RDONLY))<0)
printf("cant open fifo to write");
if((fdb=open("FIFO2", O_WRONLY))<0)
printf("cant open fifo to read");
read(fda, x.letter, sizeof(char)); //read the character
read(fda, x.number, sizeof(int)); //read the integer
printf("\nServer: just got character: , %c", x.letter[0]);
printf("\nServer: just got integer: , %d", x.number[0]);
p=x.number[0];
if (p > 6) p = 6; // Cannot write more than 6 characters in outletter
for( i = 0; i<=p; i++) { // iteration to create the character's string
outletter[i] = x.letter[0];
printf("iteration: %d and character: %c\n", i, outletter[i]); // validating the character and integer received
}
outletter[p] = '\0'; // the string must finish with '\0'
printf("\nServer: outchar is, %s", outletter); // this shows the character to be sent back to client
write(fdb, outletter, p);
printf("\nServer: Got the characters sent: %s", outletter ); // this sends the letter back to client
if(finish == 1)
printf("\nServer: This says I am ready to close ");
close(fda);
close(fdb);
unlink("FIFO1");
unlink("FIFO2");
}

c - How to check EOF when read() on FIFO

In a client-server program, need check EOF for read() on a FIFO?
Questions:
Does EOF in FIFO return 0, or -1 with errno set?
Does the rule also apply to other IPC facilities?
#Update
I still found the result wield, so need to continue ask about it.
Following are the source code:
cs_fifo.h:
// fifo header
#ifndef _CS_FIFO
#define _CS_FIFO
#define CLIENT_DATA_SIZE 2
#define SERVER_DATA_SIZE 10
#define SERVER_FIFO_PATH "/tmp/server_fifo"
#define CLIENT_COUNT 3
#endif
fifo_server.c:
// client - server fifo, server part,
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "cs_fifo.h"
int fifo_server() {
int flag;
int fd;
char buf[CLIENT_DATA_SIZE];
// remove fifo, before create
remove(SERVER_FIFO_PATH);
// create fifo
mode_t mode = 0644;
if((flag = mkfifo(SERVER_FIFO_PATH, mode)) == -1) {
printf("error while mkfifo(): %s\n", strerror(errno));
return -1;
}
printf("server fifo created, path: %s\n", SERVER_FIFO_PATH);
// open for read
if((fd = open(SERVER_FIFO_PATH, O_RDONLY)) == -1) {
printf("error while open(): %s\n", strerror(errno));
exit(-1);
}
// loop to receive data from client,
while(1) {
// read from fifo
if((flag = read(fd, buf, CLIENT_DATA_SIZE)) == -1) {
printf("error while read(): %s\n", strerror(errno));
exit(0);
} else if(flag == 0) { // no data
printf("no data\n");
sleep(1);
continue;
}
// data received,
printf("receive data: %s\n", buf);
// send data back to client's fifo,
// TODO
}
// remove fifo, after finish using,
remove(SERVER_FIFO_PATH);
return 0;
}
int main(int argc, char * argv[]) {
return fifo_server();
}
fifo_client.c:
// client - server fifo, client pool part,
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "cs_fifo.h"
int fifo_client_pool() {
int flag;
int server_fd;
char data[CLIENT_DATA_SIZE];
int i = 0;
pid_t cpid;
char identity;
// open for write
if((server_fd= open(SERVER_FIFO_PATH, O_WRONLY)) == -1) {
printf("error while open(): %s\n", strerror(errno));
exit(-1);
}
// create child processes as clients,
while(i < CLIENT_COUNT) {
switch(cpid=fork()) {
case -1: // failed
printf("error while fork(): %s\n", strerror(errno));
exit(errno);
case 0: // success, child process goes here
printf("child process created, pid [%d], parent pid [%d]\n",(int)getpid(), (int)getppid());
identity = i + 65; // start from 'A'
// prepare data
data[0] = identity;
data[1] = '\0';
// write to fifo
if((flag = write(server_fd, data, CLIENT_DATA_SIZE)) == -1) {
printf("[%c] error while write(): %s\n", identity, strerror(errno));
_exit(-1);
}
printf("[%c] send data to server\n", identity);
_exit(0);
break;
default: // success, parent process goes here
// sleep a while,
sleep(1);
break;
}
i++;
}
if((flag = close(server_fd)) != 0) {
printf("error while close(): %s\n", strerror(errno));
}
return 0;
}
int main(int argc, char * argv[]) {
return fifo_client_pool();
}
Compile:
Server: gcc -Wall fifo_server.c -o server
Client: gcc -Wall fifo_client_pool.c -o client_pool
Execute:
First start server: ./server
Then start client pool: ./client_pool
Result:
Server start, and blocks before client start.
Then client start, and server receive 1 request from each of the 3 clients, that's 3 in total.
Then all client processes terminated, then server's read() continue return 0 without blocked.
The future question is:
After all clients terminated, shouldn't server's read() block? Since it's in blocking mode?
All reads from a descriptor where read returns zero means "closed" or "end".
If you have a blocking descriptor (the default) then read will block if there's currently nothing to read. If the descriptor is non-blocking then read returns -1 with errno set to EAGAIN or EWOULDBLOCK if there's nothing to read.

Resources