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