/*IMPLEMENTATION OF CLIENT-SEVER ROJECT WITH 4 FIFO...3 CLIENTS...3 SEMAPHORES..TO SYNCHRONISE THE FIFOS*/
//LET THE READER NOT READ UNTILL WRITER WRITERS...&...READ BEFORE WRITER FINISHES
//linux/sem.h contains semctl function "union semun{ " ...& also sys/ipc.h is included...so no need to define this union here in server...
//semaphore will operate clients one by one serial wise 70%...as clients are coming ./client1 & ./client2 & ./client3..but in 30%..it may not be operated clients serial wise....its main purpose it to operate complete code in which it is applied ...i.e. called critical section of code...
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<unistd.h>
//#include<sys/ipc.h>
#include<sys/types.h>
#include<linux/sem.h>
/*union semun
{
int val;
};*/
union semun init;//variable of "union semun{" is declared
int main()
{
int ret,cid,tid,kid;//semget returns semaphore id
kid=semget(777,1,777|IPC_CREAT);//3 semaphores are created...1st arg is any +value by which semaphore is identified in all files..or processes where we are going to use it...
tid=semget(778,1,777|IPC_CREAT);//2nd arg is no. of semaphores
cid=semget(779,1,777|IPC_CREAT);//3rd arg is permissions..|IPC_CREAT is used to creat semaphore
//ret=semctl(kid,0,IPC_RMID,0);
//printf("ret=%d\n",ret);
init.val=1;
if(!semctl(kid,0,SETVAL,init))
printf("sem initialised\n");//all the semaphore are initialised by value=1..
if(!semctl(tid,0,SETVAL,init))
printf("sem initialised\n");//initialised using same variable of union defined above
if(!semctl(cid,0,SETVAL,init))//while initialisation ...only 1st arg is changed..i.e.semid
printf("sem initialised\n");
int wfd,fd,i=0,count=0,res=0;
int buff[3];
ret=mkfifo("rfifo",777|IPC_CREAT);//4 fifos are created /.//2 for client & 2 for process..
//1 fifo for taking request ....2nd fifo for sending result ..either to 3 clients ||to 3 processes
if(ret==0)
printf("fifo created\n");
ret=mkfifo("profifo",777|IPC_CREAT);
if(ret==0)
printf("fifo created\n");
ret=mkfifo("resfifo",777|IPC_CREAT);//name of fifo is 1st arg..permissions are given in 2nd
if(ret==0)
printf("fifo created\n");
for(i=0;i<3;i++)//loop for 3 clients is applied
{
printf("\ni=%d\n",i);
fd=open("rfifo",O_RDONLY);//fifo will block on open untill there is no writer opened at O_WRONLY mode on other side
printf("fd=%d\n",fd);//as writer is opened in any of client in other side...means ./client1 & ./client2 & ./client3 will operate 3 clients at the same time ...in background process.....so semaphore will synchronise 3 clients.....& make possible them write one by one..on the same time other clients will hold in waiting queue...
count=read(fd,buff,9);//9 bytes are read by 1st client..then 2nd..then 3rd
sleep(9.9999/10);//Dont take me wrong....i m not making server to wait...but it is necessary.....because in fifo..there is no NON_BLOCK condition is applied by me.....so it is compulsary that ...in the time in which writer is writer should be the same time reader is reading...means writer should be there if reader have to read...||reader should be there if writer have to write...so let the reader not to read ..untill writer writes ...& let it read..before writer finishes...... wfd=open("profifo",O_WRONLY);// AFTER reading client ...put data in processing fifo..to do process
printf("wfd=%d\n",wfd);//open processing fifo in O_WRONLY mode
count=write(wfd,buff,9);//write those 9 bytes into processing fifo
printf("count to process=%d",count);//count=9..no. of bytes writen will be returned by read() ||write() system call
}
close(fd);close(wfd);//close fds
for(i=0;i<3;i++)
{
fd=open("respfifo",O_RDONLY);//open processing result fifo ..in O_RDONLY mode to read the result frm process...it will block on open..untill one of process open at O_WRONLY mode..
printf("fd=%d\n",fd);
count=read(fd,&res,4);//as one of process open same fifo on other side in O_WRONLY mode...reader will got signal...it will start reading from fifo..& go on reading all there processes ..so all process have to write into it..untill statement come again in for loop..other u may use close(fd),,again open will go block on open again..remain block untill..2nd writer writes
printf("count from process=%d\n",count);
printf("###############result=%d#################\n",res);//for loop is so fast..let reader not read before writer writes
if(semop(cid,&a,1) != -1)//other semaphore is acquired here to synchronise processes...same semaphore as of client is not used here..bcz 1st it will make time 2 times to operate..2nd..single semaphore cant handle all proccesses & all clients in synchronisation at the same time..
printf("semac 1 p1\n");
fd=open("profifo",O_RDONLY);//open processing data fifo in rdonly mode...it will block untill..on other side ..its writer not opened to write
a.sem_op=1;//sem is released & acquired by other process
a.sem_flg=SEM_UNDO;
if(semop(cid,&a,1) != -1)
printf("semrs 1 p1\n");
res=buff[0]+buff[1];//data is processed
printf("res=%d\n",res);
//tid=semget(778,1,777);
//printf("tid=%d\n",tid);
a.sem_num=0;
a.sem_op=-1;//3rd semaphore will synchronise all the writers of result in all processes...so that.....when reader start...all the writers do not write at same time...
a.sem_flg=SEM_UNDO;
if(semop(tid,&a,1) != -1)
printf("semac p1\n");
printf("semac p1\n");
wfd=open("respfifo",O_WRONLY);
count=write(wfd,&res,4);//after writing into result fifo of process to server..sem will be acuired to other process to write same result......