Write your own simple client/server set of processes in the C language. There sh
ID: 3845959 • Letter: W
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 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 <unistd.h>
#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)) < 0)
oops("shmget", 1);
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 <unistd.h>
#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 != ''; s++)
//putchar(*s);
//}
while(1)
{
wait_and_lock( semset_id );
printf( " shm_ts2 update memory " );
if(strcmp(memPtr, "HI")==0)
{
printf("Greetings! ");
fflush(stdout);
memPtr[0] = '';
}
else if(strcmp(memPtr, "PID")==0)
{
id = (int)getpid();
printf("Server pid: %i ", id);
fflush(stdout);
memPtr[0] = '';
}
else if(strcmp(memPtr, "QUIT")==0){
shmctl(seg_id, IPC_RMID, NULL);
shmdt(memPtr);
printf("GOODBYE! ");
exit(0);
}
release_lock( semset_id );
printf( " shm_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 );
}
Explanation / Answer
server.c
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.