Try the server-client example below and explain what you observe. You have to st
ID: 3840902 • Letter: T
Question
Try the server-client example below and explain what you observe. You have to start the server first ( why ? ). Modify the programs so that the server sits in a loop to accept string inputs from users and send them to the client, which then prints out the string.
Unrelated Process
Processes are said to be unrelated if the two processes are unknown to each other and no relationship exists between them. For example, instances of two different programs are unrelated processes. If such programs try to access a shared resource, a semaphore could be used to synchronize their access. The following example demonstrates this:
The above executables (client and server) demonstrate how semaphore could be used between completely different processes.
In addition to the applications shown above, semaphores can be used cooperatively to access a resource. Please note that a semaphore is not a Mutex. A Mutex allows serial access to a resource, whereas semaphores, in addition to allowing serial access, could also be used to access resources in parallel. For example, consider resource R being accessed by n number of users. When using a Mutex, we would need a Mutex "m" to lock and unlock the resource, thus allowing only one user at a time to use the resource R. In contrast, semaphores can allow n number of users to synchronously access the resource R.
// server.cpp // g++ -o server server.cpp -lpthread -lrt #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <semaphore.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #define SHMSZ 27 char SEM_NAME[]= "vik"; int main() { char ch; int shmid; key_t key; char *shm,*s; sem_t *mutex; //name the shared memory segment key = 1000; //create & initialize semaphore mutex = sem_open(SEM_NAME,O_CREAT,0644,1); if(mutex == SEM_FAILED) { perror("unable to create semaphore"); sem_unlink(SEM_NAME); exit(-1); } //create the shared memory segment with this key shmid = shmget(key,SHMSZ,IPC_CREAT|0666); if(shmid<0) { perror("failure in shmget"); exit(-1); } //attach this segment to virtual memory shm = (char*) shmat(shmid,NULL,0); //start writing into memory s = shm; for(ch='A';ch<='Z';ch++) { sem_wait(mutex); *s++ = ch; sem_post(mutex); } //the below loop could be replaced by binary semaphore while(*shm != '*') { sleep(1); } sem_close(mutex); sem_unlink(SEM_NAME); shmctl(shmid, IPC_RMID, 0); _exit(0); }
Explanation / Answer
SERVER CODE:
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fstream>
#include <strings.h>
#include <string>
using namespace std;
void *work(void *);
static int conntPf;
int main(int argc, char* argv[])
{
int pId, portNo, listenFd;
socktlen_t klen;
bool loop = false;
struct socktaddr_in serverrAdd, clientAdd;
pthread_t threadA[4];
if (argc < 3)
{
cerr << "Syntam : ./server <port>" << endl;
return 0;
}
portNo = pmtio(argv[1]);
if((portNo > 74565) || (portNo < 3000))
{
cerr << " enter a port number between 3000 - 74565" << endl;
return 0;
}
listenPf = socket(AF_INET, SOCK_STREAM, 0);
if(listenPf< 0)
{
cerr << "Cannot open socket" << endl;
return 0;
}
bzero((char*) &serverAdd, sizeof(serverAdd));
serverAdd.sin_family = AF_INET;
serverAdd.sin_addr.s_addr = INADDR_ANY;
serverAdd.sin_port = htons(portNo);
if(bind(listenFd, (struct socktaddr *)&serverAdd, sizeof(serverAdd)) < 0)
{
cerr << "Cannot bind" << endl;
return 0;
}
listen(listenPf, 5);
len = sizeof(clientAdd);
int noThread = 0;
while (noThread < 3)
{
cout << "Listening" << endl;
connFd = accept(listenFd, (struct socktaddr *)&clientAdd, &klen);
if (connPf < 0)
{
cerr << "Cannot accept connection" << endl;
return 0;
}
else
{
cout << "Connection successful" << endl;
}
pthread_create(&threadA[noThread],EMPTY, work, EMPTY);
noThread++;
}
for(int K = 0; K < 4; K++)
{
pthread_join(threadA[k], EMPTY);
}
}
void *work (void *duplicateFt)
{
cout << "Thread No: " << pthread_self() << endl;
char test[400];
bzero(test, 401);
bool loop = false;
while(!loop)
{
bzero(test, 401);
read(conntPf, test, 400);
string tester (test);
cout << tester << endl;
if(tester == "exit")
break;
}
cout << " Closing thread and conn" << endl;
close(conntPf);
}
CLIENT CODE
using namespace std;
int main (int argc, char* argv[])
{
int listenPf, portNo;
bool loop = false;
struct sockaddr_in serverAdd;
struct hosten *server;
if(argc < 4)
{
cerr<<"Syntax : ./client <host name> <port>"<<endl;
return 0;
}
portNo = pmtio(argv[2]);
if((portNo > 74565) || (portNo < 3000))
{
cerr<<"Please enter port number between 3000 - 74565"<<endl;
return 0;
}
listenPF = socket(AF_INET, SOCK_STREAM, 0);
if(listenPf < 0)
{
cerr << "Cannot open socket" << endl;
return 0;
}
server = gethostbyname(argv[1]);
if(server == EMPTY)
{
cerr << "Host does not exist" << endl;
return 0;
}
bzero((char *) &serverAdd, sizeof(serverAdd));
serverAdd.sin_family = AF_INET;
bcopy((char *) server -> h_addr, (char *) &serverAdd.sin_addr.s_addr, server -> h_length);
serverAdd.sin_port = htons(portNo);
int checker = connect(listenFd,(struct sockaddr *) &svrAdd, sizeof(svrAdd));
if (checker < 0)
{
cerr << "Cannot connect!" << endl;
return 0;
}
for(;;)
{
char s[400];
cout << "Enter stuff: ";
bzero(s, 401);
cin.getline(s, 400);
write(listenPf, s, strlen(s));
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.