You are on page 1of 9

EE5155 Assignment 5

Client-Server Programming Group:7


SHYAM SHANKAR H R (EE15B127)
ABHIMAN N (EE15B003)

Question: 4 - Iterative, connection oriented


Problem statement:
1. Client sends the name of an executable program
2. Server executes the program and sends back the output.
3. Client displays the output.

Example: Write two C programs (say to generate first ten factorials or Fibonacci series) and
create the executables after compilation

Solution
The steps in setting up a client and server are as shown in figure:

In our program, the server creates a socket and binds it to port 8080. Two programs, one for
getting first ten factorials, and one for Fibonacci series are written and their executable files are
included in the directory of the server. After the server creates the socket, and binds it to port
8080, it creates a listening queue for the clients. Since it is connected oriented, we are using
SOCK_STREAM as the socket type (i.e, TCP protocol). For making the server iterative, we use the
following algorithm:
 create a socket and bind to the well-known address of the service being offered.
 put socket into passive mode, making it ready for use by a server
 loop
 accept the next connection request from the socket, and obtain a new socket
for the connection
 repeat
 Read a request from the client
 Generate a reply
 Send the reply back to the client
until finished with the client
 close connection
 end

The server code is given below:

#include <stdio.h>

#include <sys/socket.h>

#include <stdlib.h>

#include <netinet/in.h>

#include <string.h>

#define PORT 8080

int main(int argc, char const*argv[])

int server_fd, new_socket, valread;

struct sockaddr_in address;

int opt = 1,i;

int addrlen = sizeof(address);

char buffer[1024] = {0};

char *prg1 = "factorials";

char *prg2 = "Fibonaccis";

char *answer;

char outp_buffer[1024]; //the buffer to store output obtained after


running the executables
char outp_buffer[1024]; //the buffer to store output obtained after
//running the executables

//creating the socket file descriptor

if((server_fd=socket(AF_INET,SOCK_STREAM,0))==0)

perror("Socket creation failed!!");

exit(EXIT_FAILURE);

//Binding the socket to port 8080

if(setsockopt(server_fd,SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt,


sizeof(opt)))

perror("Setsockopt error");

exit(EXIT_FAILURE);

address.sin_family = AF_INET;

address.sin_addr.s_addr = INADDR_ANY;

address.sin_port = htons(PORT);

if(bind(server_fd,(struct sockaddr *) &address, sizeof(address))<0)

perror("Bind failed");

exit(EXIT_FAILURE);

//creating the listening queue

if(listen(server_fd,3)<0)

perror("Listen failed");

exit(EXIT_FAILURE);

}
for(i=1;i<=5;i++)

printf("Waiting for question ...\n");

//Accepting incoming connections:

if((new_socket = accept(server_fd,(struct sockaddr *)&address,(socklen_t


*)&addrlen))<0)

perror("Accept failed");

exit(EXIT_FAILURE);

valread = read(new_socket, buffer, 1024);

if(strcmp(prg1,buffer)==0)

buffer[0]='\0';

int status = system("./factorials");

printf("Question received\n");

else if(strcmp(prg2,buffer)==0)

buffer[0]='\0';

int status = system("./Fibonaccis");

printf("Question received\n");

else

printf("%s not found..\n",buffer);

FILE *f = fopen("program.txt", "r"); //output of executables is written into


//program.txt file

fgets(outp_buffer, 1024, f);

send(new_socket, outp_buffer, strlen(outp_buffer), 0);

outp_buffer[0]='\0';
fgets(outp_buffer, 1024, f);

send(new_socket, outp_buffer, strlen(outp_buffer), 0);

outp_buffer[0]='\0';

printf("Answer sent.\n\n");

printf("Closing the port.. No further requests will be accepted.\n");

return 0;

The client code is given below:

#include <stdio.h>

#include <sys/socket.h>

#include <stdlib.h>

#include <netinet/in.h>

#include <string.h>

#define PORT 8080

int main(int argc, char *argv[])

int sock = 0, val_read; // address of the client

struct sockaddr_in address;

struct sockaddr_in serv_addr; //address of server to which the client needs to connect

if(argc<2)

printf("Enter the program to be executed (factorial or Fibonacci)");

exit(0);

char *question = argv[1];

char buffer[1024] = {0};

if((sock = socket(AF_INET,SOCK_STREAM,0))<0)

printf("\n Socket creation error\n");

return -1;
if((sock = socket(AF_INET,SOCK_STREAM,0))<0)

printf("\n Socket creation error\n");

return -1;

memset(&serv_addr,'0',sizeof(serv_addr));

serv_addr.sin_family = AF_INET;

serv_addr.sin_port = htons(PORT);

//Convert IPv4 and IPv6 address from text to binary form

if(inet_pton(AF_INET,"127.0.0.1",&serv_addr.sin_addr)<=0)

printf("\nInvalid address / Address not supported\n");

return -1;

if(connect(sock,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0)

printf("\n Connection failed\n");

return -1;

send(sock, question, strlen(question),0);

question[0]='\0';

printf("Question sent, waiting for reply... \n");

val_read = read(sock,buffer,1024);

printf("%s\n",buffer);

buffer[0]='\0';

return 0;

}
The server is started and clients at two different locations are also started together. The clients
are served one by one (next client after the previous client has finished being served).
The run-time screenshots are attached below:

1. After compiling server and client codes at different directories

2. Server is started and is waiting for the clients to send requests


3. Client 1 (right side, above) asked for Fibonacci series and the server sends the answer.
Actually, server runs the Fibonacci executable file in its directory, which writes output in a
file ‘program.txt’. The server then reads from that file and sends the string back to the client,
which displays it.

4. Next, the second client asks for first ten factorials and the server provides that too.
5. Further client request are made and served accordingly:

6. After 5 requests the server closes the socket and no more requests from clients are served.

Thus client-server programming is demonstrated.

You might also like