cs270 - Assignment 3 - Patrick Du

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 13

Du 1

Patrick Du
Professor Bolden
CS 270
15 November 2023
Design:
I. Overview
Write a client-server calculator program that callculates values beased on an operator and
two integers. Input for the calculator should be client side in prefix notation, and the
output as well as calculations should be handled server side. Use ports 4500-4525.

II. Outline
A. Client.c
1. Responsible for input from the user
2. In my case I would connect to server using localhost
3. Really just the sample code provided without much alteration
B. Server.c
1. Also using sample code for server, but making modifications to later half
of the code after reading from client to make a calculator.
2. Switch case for calculation
3. Small tokenizer to get operator, number1, and number2
C. Makefile
1. Dependencies: server.o client.o
Du 2

III. Log
A. 11 November (~an hour)
1. Started work on the assignment by reading the attached link to the
server/client sample code.
2. After about an hour of reading and copying the code over to see how the
server/client interact with each other, feeling ready to start the actual
assignment
B. 12 November (~4 hours)
1. Started coding the assignment today, really easy implementation based off
the sample code provided by the website.
2. Client.c was for the most part unchanged
3. Server.c is where I did most of the coding, really just tokenizing the
character array that the server reads into.
4. Important to remember to close the sockets.
5. Now that the code is working properly and I can get the client and server
to communicate, it is time to make the makefile
6. Makefile was simple after some brushing up, took around 30 min.
Du 3

IV. Results
A. Addition:

B. Subtraction:

C. Multiplication:

D. Division:

E. Modulo:
Du 4

F. Makefile:

G. Error Checking:
Du 5

V. Program
- server.c
/* server.c
Patrick Du CS 270
code based off online sample code:
https://www.linuxhowtos.org/C_C++/socket.htm

Run:
gcc server.c -o server
./server [port_Number]

*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

void error(const char *msg)


{
perror(msg);
exit(1);
}

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


{
int sockfd, newsockfd, portno;
socklen_t clilen;
Du 6

char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");

//section that reads whatever is in the socket and stores it in buffer


bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
Du 7

int result = 0;
int iterate = 0;

//remove whitespace to tokenize buffer


while( isspace(buffer[iterate]) ){ iterate++;}

//strchr to determine if operator is valid


if( strchr("+-*/%", buffer[iterate]) == NULL){
printf("invalid entry, ensure operation is supported (+,-,*,/,%)\n");
printf("Calculator takes prefix notation. Exitting...\n");
close(newsockfd);
close(sockfd);
return 0;
}
else{
//calculator
char operation = buffer[iterate];
iterate++;

int no1 = 0;
int no2 = 0;

//find first number:


while( isspace(buffer[iterate]) ){ iterate++;}
int end = 0;
//find end of first number:
while( !isspace(buffer[iterate+end+1]) ){ end++;}
//turn into int using for loop
for( int i = iterate; i < iterate+end+1; i++){
no1 = no1 * 10 + (buffer[i] - 48);
}
Du 8

iterate = iterate + end + 1;

//find second number:


while( isspace(buffer[iterate]) ){ iterate++;}
end = 0;
//find end of first number:
while( !isspace(buffer[iterate+end+1]) ){ end++;}
//turn into int using for loop
for( int i = iterate; i < iterate+end+1; i++){
no2 = no2 * 10 + (buffer[i] - 48);
}

//calculator code
switch(operation){
case '+':
result = no1 + no2;
break;
case '-':
result = no1 - no2;
break;
case '*':
result = no1 * no2;
break;
case '/':
result = no1 / no2;
break;
case '%':
result = no1 % no2;
break;
default:
Du 9

printf("Error, invalid operation\n");


}
printf("%d %c %d = %d\n",no1,operation,no2,result);
close(newsockfd);
close(sockfd);
return 0;
}
}
Du 10

- client.c
/* client.c
Patrick Du CS 270
code based off online sample code:
https://www.linuxhowtos.org/C_C++/socket.htm

Run:
gcc client.c -o client
./client [host_Name/localhost] [port_Number]

*/
#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 <netdb.h>

//error msg from sample code


void error(const char *msg)
{
perror(msg);
exit(0);
}

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


{
Du 11

int sockfd, portno, n;


struct sockaddr_in serv_addr;
struct hostent *server;

char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");

//really the only thing I changed in client.c is the line below:


printf("Please enter a prefix equation containing a valid operator (+,-,*,/,%): ");
bzero(buffer,256);
fgets(buffer,255,stdin);
Du 12

n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
close(sockfd);
return 0;
}
Du 13

- Makefile
# Patrick Du, MakeFile for server.c and client.c

program: server.o client.o

server.o: server.c
gcc server.c -o server

client.o: client.c
gcc client.c -o client

clean:
rm client server

You might also like