/**
* Files : Palindrome_client.cc
* Name : Edison
Chindrawaly
* Class : CSCI 3780
Spring 2001
* HW : #3
*/
#include "MyHeader.h"
char*
askIP(char *);
char* askPort(char *);
void processIt(char* , char*
);
int openConnection(char *, char *);
void
closeConnection(int);
int sendAll(int, char *);
int receiveAll(int,
char *);
//interact with user
int getUserChoice(void);
void
getUserFile(int );
void getUserInput(int );
void main(int
argc, char **argv)
{
char*
tempAdd;
char* IP_add = strdup(askIP(tempAdd));
char* Host_port = strdup(askPort(tempAdd));
processIt(IP_add, Host_port);
exit(0);
}
/**
* askIP's method is to ask user for the host
IP add
* @param char* tAdd
* @return char* IP
address
*/
char* askIP(char*
tAdd)
{
char temp[16+1];
cout<<"Enter the hostname (e.g.
csp04) : "<<flush;
cin.getline(temp,17);
strcpy(tAdd,temp);
return tAdd;
}
/**
* askPort's method is to ask user for the host port number.
* The host port number has a max of 6
digits
* @param char* taAdd
* @return char* the port number of user.
*/
char* askPort(char* tAdd)
{
char temp[5+1];
cout<<"Enter the host port:
"<<flush;
cin.getline(temp,6);
strcpy(tAdd,temp);
return
tAdd;
}
/**
*
openConnection's method is to open connection to host server
* with the given IP address and the given
port number. Once the
* server
accepts the connection, openConnection's method will
* return the sockfd of the accepted/rejected
connection.
* @param char* ipAdd contains host IP address
*
char* hostPort contains host port number
* @return int sockfd contains the sock descriptor of the
accepted
or rejected
connection(-1)
*/
int
openConnection(char* ipAdd, char* hostPort)
{
int sockfd;
struct hostent *hosten;
struct sockaddr_in serv_addr;
if((hosten = gethostbyname(ipAdd)) ==
NULL)
{
perror("Error: need hostname!
");
exit(1);
}
if((sockfd=socket(AF_INET, SOCK_STREAM,IPPROTO_TCP))==-1)
{
perror("socket error");
exit(1);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(atoi(hostPort));
serv_addr.sin_addr =
*((struct in_addr *)hosten->h_addr);
bzero(&(serv_addr.sin_zero),8);
if(connect(sockfd,(struct sockaddr
*)&serv_addr,
sizeof(struct
sockaddr))==-1)
{
perror("connect error");
exit(1);
}
return
sockfd;
}
/**
*
processIt's method is to process the part of
* getting user input and
send the user input [palindrome]
*
to the server to be process by the server. It turns
* the server will return array contains
answer to
* the user input.
* @param
char* ipAdd contains host ip address
* char* hostPort
contains host port number
*
@return none
*/
void
processIt(char* ipAdd, char* hostPort)
{
int sockfd = openConnection(ipAdd,hostPort);
int numbytes;
char buffer[MAXSIZE];
if((numbytes=recv(sockfd, buffer, MAXSIZE, 0)) == -1)
{
perror("recv error");
closeConnection(sockfd);
exit(1);
}
buffer[numbytes] = '\0';
printf("Received: %s",
buffer);
strcpy(buffer,"reply
to server: hello server\n");
send(sockfd,buffer,strlen(buffer),0);
int respond = 0;
do
{
respond =
getUserChoice();
switch(respond)
{
case 1:
getUserInput(sockfd);
break;
case 2:
getUserFile(sockfd);
case 3: break;
}
} while(respond != 3);
closeConnection(sockfd);
}
/**
* closeConnection's method is to close the
socket
* @param int sockfd contains the connection
socket
* @return none
*/
void closeConnection(int sockfd)
{
close(sockfd);
}
/**
* getUserChoice's method is to get user
choice whether
* the user wants to
input from keyboard or file
*
@param none
* @return choice = 1 to enter from
keyboard
* choice = 2 to enter from file
*
choice = 3 to exit
*/
int
getUserChoice()
{
int choice
= 0;
do
{
cout<<"Would you like to: "<<endl;
cout<<"1. Enter the words
manually."<<endl;
cout<<"2. Enter the words from the
file."<<endl;
cout<<"3. Exit."<<endl;
cout<<"NOTE: max length of word =
128 characters.\n"<<endl;
cout<<"Your choice : "<<flush;
cin>>choice;
if((choice == 1) || (choice == 2) || (choice
== 3))
return choice;
cout<<"Invalid
choice!"<<endl;
}
while(1);
}
/**
*
getUserInput's method is to getUserInput from keyboard
* It uses array of char with MAXSIZE of 128
words. The
* process of reading
user input will end when user type END
* or the count has reach 127 [MAXSIZE-1].
* @param
char[] msgbuffer contains nothing
* @return msgbuffer[] contain users input
*/
void getUserInput(int sockfd)
{
int count = 0;
char buf[MAXSIZE];
cout<<"Enter the words you want to
enter(max length=128)\n";
cout<<"Type END to end the process\n";
do
{
buf[0]='\0';
cout<<"word :
"<<flush;
cin.getline(buf,MAXSIZE);
if(strcasecmp(buf,"END") == 0)
break;
if(sendAll(sockfd,buf) < 0)
{
perror("send
error\n");
closeConnection(sockfd);
exit(0);
}
if(receiveAll(sockfd,buf) < 0)
{
perror("receive error\n");
closeConnection(sockfd);
exit(0);
}
}while(true);
}
/**
* getUserFile's method is to get user input
from the
* given file (user
determine the file.) This method
* assumed that the file is in the current directory.
* @param
char* msgBuffer contains empty string
* @return char* the result of the reading user input
*/
void getUserFile(int sockfd)
{
char buffer[MAXSIZE];
char filename[20+1];
cout<<"Enter the file name: "<<flush;
cin>>filename;
if(strlen(filename)<1)
{
cout<<"You need to enter the
filename"<<endl;
exit(0);
}
ifstream readfile(filename);
if(!readfile.is_open())
{
cout<<"Unable to open the file:
"<<filename<<endl;
exit(0);
}
while(!readfile.eof())
{
readfile.getline(buffer,MAXSIZE);
if(sendAll(sockfd,buffer) < 0)
{
perror("send error\n");
closeConnection(sockfd);
readfile.close();
exit(0);
}
if(receiveAll(sockfd,buffer) < 0)
{
perror("receive error\n");
closeConnection(sockfd);
readfile.close();
exit(0);
}
}
readfile.close();
}
/**
* sendAll's method is to send string with the
* given socket file descriptor to
the host.
* @param int sockfd contains socket descriptor
*
char* buffer contains the string to send
* @return int = 0 if successful else -1
*/
int sendAll(int sockfd, char*
buffer)
{
int sendBytes =
0;
int total = 0;
int length = strlen(buffer);
int bytesleft = length;
while(total < length)
{
sendBytes =
send(sockfd, buffer+total, bytesleft, 0);
if(sendBytes == -1)
break;
total
+= sendBytes;
bytesleft -=
sendBytes;
}
length = total;
return sendBytes==-1? -1:0;
}
/**
* receiveAll's method is to receive message
of 0 & 1
* 0 means not
palindrome. 1 means palindrome.
*
@param int sockfd contains socket
descriptor
* char* original contains original
string
* @return int -1 if it fails
else return 0 if successfull
*/
int receiveAll(int sockfd, char* original)
{
char buffer[MAXSIZE];
int numbytes = 0;
if((numbytes=recv(sockfd,buffer,MAXSIZE,0))<0)
{
perror("received error from server\n");
return -1;
}
buffer[numbytes] =
'\0';
if(buffer[0] == '0')
printf("The word %s is not a
palindrome.\n",original);
else if(buffer[0] == '1')
printf("The word %s is a palindrome.\n",original);
return 0;
}