Friday, May 19, 2017

Network Programming - Second Semester 2016-17 : ASSIGNMENT NO - 1

ASSIGNMENT NO:1 


Q1) Design a concurrent TCP server to using poll functions to echo the text message. 


DESCRIPTION: Poll provides functionality that is similar to select, but poll provides additional information when dealing with streams devices.

#include <poll.h>
int poll ( struct pollfd *fdarray, unsigned long nfds, int timeout);
returns : count of ready descriptors, 0 on timeout, -1 on error. 

The return value from poll is -1 if an error occurred, 0 if no descriptors are ready before the time expires, otherwise it is the number of descriptors that have a nonzero revents member. The first argument is a pointer to the first element of an array of structures. Each element of the array is a pollfd structure that specifies the condition to be tested for a given descriptor fd. 

Structure pollfd { 
                                 Int fd; 
                                 Short events; 
                                 Short revents; 
                           } 

Pseudo code for SERVER: 

START 

Declare structure variables for Server socket data 
take character buffers to store data 
create IPV4 socket by calling socket() system call 
if socket system call returns -1 
then 
         perror 
         exit 
Initialize server socket 
Bind server to an IP address 
If bind system call returns -1 
Then 
                 Perror unable to bind 
                 Exit 
Listen for clients on port 
While true 
                   Poll for client descriptors 
                   Accept connections from client 
                   If recv less than zero 
                              Print error no 
                   Else 
                              Accept data from client and store in character buffers 
                              Print received data 
                              Send data received from client again to client 
                   Close the connection 
END 


Pseudo code for CLIENT 

START 

Declare sock as integer variable 
Declare character arryas named fname and op 
Declare a file pointer variable named fp 
Declare variables named server_addr for sockaddr_in structure 
If socket system call returns -1 
Then 
             Perror socket 
             Exit 
Call marmoset system call to set the no of bytes to the value cin the destination 
Set server_addr.sin_family=AF_INET 
Set server_addr.sin_port=htons(40000) 
Set server_addr.sin_addr.s_addr=inet_addr(“127.0.0.1”) 
Call bzero system call to set the specified no of bytes to 0 
If connect system call returns -1 
Then 
                Perror connect 
                Exit 
While true 
                 Print enter file name 
                 Read fname 
                 Send file to socket 
                 Receive file from the socket 
                 Print the contents in the file 
                 Open file in write mode 
                 Write contents to file 
                 Print file sent successfully 
                 Close file 
                 Break 
                 Close socket 
                 Return 0 
END



Solution of Assignment 1: 

server.c

//header files
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<poll.h>
#include<errno.h>

#define SERV_PORT 40000
#define OPEN_MAX 5
#define LISTENQ 5
#define INFTIM -1
#define MAXLINE 1024
#define TRUE 1


int main(int argc, char **argv)
{
int  i, maxi, listenfd, connfd, sockfd;
int  nready;
ssize_t n;
char buffer[MAXLINE];
socklen_t clilen;
struct  pollfd client[OPEN_MAX];
struct  sockaddr_in clientaddr, serveraddr;
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(SERV_PORT);

listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd == -1)
{
perror("socket error\n");
exit(-1);
}

if(bind(listenfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) == -1)
{
perror("unable to bind\n");
exit(-1);
}

listen(listenfd, LISTENQ);

client[0].fd = listenfd;
client[0].events = POLLRDNORM;
for (i = 1; i < OPEN_MAX; i++)
{
client[i].fd = -1; /* -1 indicates available entry */
}

maxi = 0; /* max index into client[] array */

while(TRUE)
{
printf("Waiting on poll()...\n");
nready = poll(client, maxi + 1, INFTIM);

if(nready < 0)
{
perror("poll error");
exit(-1);

}
if (client[0].revents & POLLRDNORM)
{  /* new client connection */
printf("  Listening socket is readable\n");
clilen = sizeof(clientaddr);
connfd = accept(listenfd, (struct sockaddr*) &clientaddr, &clilen);
for (i = 1; i < OPEN_MAX; i++)
{
if (client[i].fd < 0)
{
printf("  client (%d) is accepted\n", i);
client[i].fd = connfd; /* save descriptor */
break;
}
}
if (i == OPEN_MAX)
perror("too many clients");

client[i].events = POLLRDNORM;
if (i > maxi)
maxi = i; /* max index in client[] array */
if (--nready <= 0)
continue; /* no more readable descriptors */
}

for (i = 1; i <= maxi; i++)
{ /* check all clients for data */
if ( (sockfd = client[i].fd) < 0)
continue;
if (client[i].revents & (POLLRDNORM | POLLERR))
{
if ( (n = recv(sockfd, buffer, sizeof(buffer), 0)) < 0)
{

perror("recv error");
if (errno == ECONNRESET)
{
/* connection reset by client */
printf("  connection reset by client (%d)\n", i);
close(sockfd);
client[i].fd = -1;
  }
  }
else if (n == 0)
{
  /* connection closed by client */
printf("  connection closed by client (%d)\n", i);
  close(sockfd);
  client[i].fd = -1;
  }
else
{
printf("Received from client(%d) : \n %s \n",i, buffer);
  send(sockfd, buffer, n, 0);
}
  if (--nready <= 0)
{
break; /* no more readable descriptors */
}
}
}
}

}


client.c


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>

#define SERV_TCP_PORT 40000
#define SERV_HOST_ADDR "127.0.0.1"


int main(int argc,char *argv[])
{
int sockfd;
char fname[30], ip[1024], op[1024];
FILE *fp, *op_fp;
struct sockaddr_in serv_addr;

memset(ip,0,sizeof(ip));
memset(op,0,sizeof(op));
memset(fname,0,sizeof(fname));

bzero((char*)&serv_addr,sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR);
serv_addr.sin_port = htons(SERV_TCP_PORT);

if((sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1)
{
perror("socket error");
exit(0);
}

if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) == -1)
{
perror("connection error");
exit(0);
}

while(1)
{
//file handling
printf("Enter the file name: ");
scanf("%s",fname);

fp = fopen(fname,"r");
fread(ip,sizeof(char),sizeof(ip),fp);
fclose(fp);

//Send file to socket
if(send(sockfd,ip,sizeof(ip),0)!= sizeof(ip))
{
printf("\nsend command sent diff.no.of bytes");
}
else
{
printf("\nfile sent to server successfully...\n");
}

//Receive file from the socket
if((recv(sockfd,op,sizeof(op),0)) < 0)
{
printf("\nrecv() failed\n");
}
else
{
printf("\nclient rececived data from server successfully...\n");
}
//Print the contents in the file
printf("\ncontents in the file : \n %s \n",ip);

//Open file in write mode
fp = fopen("server-to-client.txt","w+");

//Write contents to file
fwrite(op,sizeof(char),sizeof(op),fp);
printf("\ndata from server stored in file server-to-client.txt...\n");
fclose(fp);
break;
}
close(sockfd);
return 0;
}






No comments:

Post a Comment