Question
Write your own simple client/server set of processes in the C language. There should be two files: client.c and server.c. The client should use a
Write your own simple client/server set of processes in the C language. There should be two files: client.c and server.c.
The client should use a shared memory segment to send a command message to the server.
You may not use sockets or multithreading, as we have not gone over that yet in my class. We are supposed to be using semaphores and shared memory segments.
The server process should monitor the shared memory segment, and respond as follows: "HI" -- The server prints "Greetings" to the screen. "PID" -- The server prints it's process id to the screen. "QUIT" -- The server terminates gracefully, detaching and releasing the shared memory segment.
**Note, please do not copy and paste a solution from here or Google. I am looking for a unique solution to help me better understand this assignment. Thank you.**
Hints :
Use polling (an intentional infinite loop) in the server to monitor the shared memory segment.
You will need some way to coordinate sharing the memory segment.
read man pages for shmdt, shmget, shmat, shmctl, semctl, semop, semget
I will now attach the code that I have so far, I am getting an error with the client.c saying "semget: File exists". I have tried changing the keys for semget but that doesn't seem to work. I don't know why it is saying I already have semaphores for those keys. The server runs fine, so far. Not sure if its done though.
Here is my server code so far:
#include "stdio.h" #include "stdlib.h" #include "sys/shm.h" #include "sys/ipc.h" #include "time.h" #include "sys/types.h" #include "sys/sem.h" #include "signal.h" #include "string.h" #include
#define MEM_KEY 90 // like a filename #define SEM_KEY 9900 #define SEG_SIZE ( (size_t)100 ) // size of segment #define oops( m, x ) { perror(m); exit(x); } int seg_id, semset_id; union semun{ int val; struct semid_ds* buf; ushort* array; }; void wait_and_lock( int ); void release_lock( int );
int main() { char c; char *memPtr;
if ((seg_id = shmget(MEM_KEY, SEG_SIZE, IPC_CREAT | 0777))
if ((memPtr = shmat(seg_id, NULL, 0)) == (char *) -1) oops("shmat", 2); semset_id = semget( SEM_KEY, 2, 0666 );
wait_and_lock( semset_id );
while(1) { printf("enter: "); scanf("%s", memPtr); }
release_lock( semset_id ); while (*memPtr != '*') sleep(1); shmdt( memPtr );
exit(0); }
void wait_and_lock( int semset_id ) { union semun sem_info; // some properties struct sembuf actions[2]; // action set, an array actions[0].sem_num = 1; // sem[1] is n_writers actions[0].sem_flg = SEM_UNDO; // auto cleanup actions[0].sem_op = 0; // wait for 0 actions[1].sem_num = 0; // sem[0] is n_readers actions[1].sem_flg = SEM_UNDO; // auto cleanup actions[1].sem_op = 1; // incr n_readers if ( semop( semset_id, actions, 2 ) == -1 ) oops( "semop: locking", 10 ); }
void release_lock( int semset_id ) { union semun sem_info; // some properties struct sembuf actions[1]; // action set actions[0].sem_num = 0; // sem[0] is n_readers actions[0].sem_flg = SEM_UNDO; // auto cleanup actions[0].sem_op = -1; // decr reader country if ( semop( semset_id, actions, 1 ) == -1 ) oops( "semop: unlocking", 10 ); }
and here is my client code so far:
#include "stdio.h" #include "stdlib.h" #include "sys/shm.h" #include "sys/ipc.h" #include "time.h" #include "sys/types.h" #include "sys/sem.h" #include "signal.h" #include "string.h" #include
#define MEM_KEY 90 // like a filename #define SEM_KEY 9900 #define SEG_SIZE ( (size_t)100 ) // size of segment #define oops( m, x ) { perror(m); exit(x); }
union semun { int val; struct semid_ds* buf; unsigned short* array; }; int seg_id, semset_id; void cleanup( int ); void set_sem_value( int, int, int ); void wait_and_lock( int ); void release_lock( int );
int main() { int id = 0; char *memPtr, *s; signal( SIGINT, cleanup ); seg_id = shmget( MEM_KEY, SEG_SIZE, 0777 ); if( seg_id == -1 ) oops( "shmget", 1 );
if ((memPtr = shmat(seg_id, NULL, 0)) == (char *) -1) oops("shmat",2); semset_id = semget( SEM_KEY, 2, ( 0666 | IPC_CREAT | IPC_EXCL ) ); if ( semset_id == -1 ) oops( "semget", 3 ); set_sem_value( semset_id, 0, 0 ); set_sem_value( semset_id, 1, 0 );
//Now read what the server put in the memory. //while(1){ //for (s = shm; *s != '\0'; s++) //putchar(*s); //} while(1) { wait_and_lock( semset_id ); printf( "\tshm_ts2 update memory " ); if(strcmp(memPtr, "HI")==0) { printf("Greetings! "); fflush(stdout); memPtr[0] = '\0';
} else if(strcmp(memPtr, "PID")==0) { id = (int)getpid(); printf("Server pid: %i ", id); fflush(stdout); memPtr[0] = '\0'; } else if(strcmp(memPtr, "QUIT")==0){ shmctl(seg_id, IPC_RMID, NULL); shmdt(memPtr); printf("GOODBYE! "); exit(0); } release_lock( semset_id ); printf( "\tshm_ts2 released lock " ); }
//putchar(' '); *memPtr = '*'; cleanup(0); return 0;
}
void cleanup( int n ) { shmctl( seg_id, IPC_RMID, NULL ); semctl( semset_id, 0, IPC_RMID, NULL ); }
void set_sem_value( int semset_id, int semnum, int val ) { union semun initval; initval.val = val; if ( semctl( semset_id, semnum, SETVAL, initval ) == -1 ) oops( "semctl", 4 ); }
void wait_and_lock( int semset_id ) { struct sembuf actions[2]; // action set, an array actions[0].sem_num = 0; // sem[0] is n_readers actions[0].sem_flg = SEM_UNDO; // auto cleanup actions[0].sem_op = 0; // wait til no readers actions[1].sem_num = 1; // sem[1] is n_writers actions[1].sem_flg = SEM_UNDO; // auto cleanup actions[1].sem_op = 1; // increment number of writers if ( semop( semset_id, actions, 2 ) == -1 ) oops("semop: locking", 10 ); }
// Thing 4: build and execute a 1-element action set: decrement num_writers void release_lock( int semset_id ) { struct sembuf actions[1]; // action set, an array actions[0].sem_num = 1; // sem[0] is n_writers actions[0].sem_flg = SEM_UNDO; // auto cleanup actions[0].sem_op = -1; // decrement number of writer count if ( semop( semset_id, actions, 1 ) == -1 ) oops( "semop: unlocking", 10 ); }
A 10-point sample run: Terminal 1: rig N$ cc cl.c ocl cat rig N HI PID QUIT trig N]$ Terminal 2 at rig ne]$ cc server.c Server crig ne]$ ./server Greetings! Server pid: 24700 GOODBYEStep by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started