/**
* Name
: Edison Chindrawaly
*
File : Palindrome_server.cc
* Class : CSCI 3780 Spring of 2001
* Desc
: This file is part of Palindrome checker's problem.
*
It servers as server which processes the list of words
*
that client submits and determine whether it is palindrome
*
or not. If it is palindrome, it will return 1 else return 0
*
It uses client/server model with TCP as the protocol.
*/
#include
"MyHeader.h"
#define BACKLOG 5
int
checkPalindrome(char*);
char* eraseWhite(char*);
int
askServerPort();
void startProcess(int);
int sendAll(int s, char
*buffer, int *length);
/**
* sigchld_handler's method is to handle
signal send by child
* this method
is taken from Beej's guide to networking with the url
* of
http://www.ecst.csuchico.edu/~beej/guide/net/html
* @param
int s (s = descriptor)
*
return none
*/
void sigchld_handler(int s)
{
wait(NULL);
}
void main(int argc, char
**argv)
{
int portNumber =
askServerPort();
startProcess(portNumber);
exit(1);
}
/**
* askServerPort's method is to ask the user for
* the host port number.
* @param
none
* @return the port
number of the host
*/
int
askServerPort()
{
int
temp;
cout<<"Enter your
server port: "<<flush;
cin>>temp;
return temp;
}
/**
* startProcess's method is to start the connection and start
* processing the a list of words that the
client sends.
* @param int numPort
* @return none
*/
void startProcess(int numPort)
{
int sockfd, fdConnect, clientSize;
struct sockaddr_in clientAdd, servAdd;
struct sigaction sa;
int yes = 1;
int pal = 0;
char
palindrome;
char* connectMsg =
"you are connected to server.\n";
// fd_set readfds;
//
FD_ZERO(&readfds);
// FD_SET(STDIN, &readfds);
sockfd = socket(AF_INET, SOCK_STREAM,
IPPROTO_TCP);
// FD_SET(sockfd,&readfds);
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1)
{
perror("setsockopt error");
exit(1);
}
bzero(&servAdd, sizeof(servAdd));
servAdd.sin_family = AF_INET;
servAdd.sin_port = htons(numPort);
servAdd.sin_addr.s_addr =
htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr *)&servAdd,sizeof(struct
sockaddr))==-1)
{
perror("bind error");
exit(1);
}
if(listen(sockfd, BACKLOG) == -1)
{
perror("listen
error");
exit(1);
}
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if(sigaction(SIGCHLD, &sa, NULL) == -1)
{
perror("sigaction error");
exit(1);
}
bool flag=false;
do
{
clientSize =
sizeof(struct sockaddr_in);
if((fdConnect=accept(sockfd,(struct sockaddr *)&clientAdd,
(socklen_t *)&clientSize)) == -1)
{
perror("accept error");
continue;
}
// FD_SET(fdConnect,
&readfds);
//
select(sockfd+1, &readfds, NULL,NULL,NULL);
cout<<"server: got connection
from "<<inet_ntoa(clientAdd.sin_addr)<<endl;
char buffer[MAXSIZE];
if(!fork())
{ // child
process
close(sockfd);
if(send(fdConnect,connectMsg,strlen(connectMsg),0)==-1)
{
perror("send error");
exit(0);
}
int numbyte=recv(fdConnect,buffer,MAXSIZE,0);
buffer[numbyte] = '\0';
pal=checkPalindrome(buffer);
if(pal == 0)
palindrome = '0';
else
palindrome = '1';
send(fdConnect,&palindrome,sizeof(palindrome),0);
close(fdConnect);
exit(0);
}
/*
if(FD_ISSET(STDIN, &readfds))
{
cout<<"A key is press\n";
flag=true;
} */
close(fdConnect); // parent closes connection
} while(flag == false); // end of while loop
}
/**
* sendAll's method is taken from Beej's
networking guide.
* The URL:
http://www.ecst.csuchico.edu/~beej/net/html/advanced.html
* This method would send a complete message.
Not a partial bits.
* @param int s: the
socket descriptor
* char * buffer: the string to be
send
* int *length: the length of the string
* @return int n (return -1 on failure.
Otherwise return 0)
*/
int
sendAll(int s, char *buffer, int *length)
{
int total = 0;
int bytesleft = *length;
int numGets;
while(total <
*length)
{
numGets = send(s, buffer+total, bytesleft,
0);
if(numGets == -1)
break;
total += numGets;
bytesleft -= numGets;
}
*length = total;
return
numGets==-1? -1:0;
}
/**
* checkPalindrome's method is to check the given string
* whether it is palindrome sentence or not.
If it is
* Palindrome, it will
return 1 else it will return 0.
*
@param char* inStr
* @return int 1 (if it is palindrome) else
0
*/
int
checkPalindrome(char* inStr)
{
char* outStr = strdup(eraseWhite(inStr));
int length = strlen(outStr);
int condition = 0;
for(int i = 0; i < length; i++)
if(i != length)
outStr[i] =
(char)tolower(outStr[i]);
else
outStr[i] =
'\0';
char* newStr = new
char;
int j = length;
for(int i=0; i < length; i++)
newStr[i] = outStr[--j];
newStr[length] = '\0';
//if
palindrome is found, return condition=1
if(strcmp(newStr,outStr) == 0)
condition = 1;
delete newStr;
delete outStr;
return condition;
}
/**
* eraseWhite's method is to erase all the
blank space
* in the given
string. The leading, trailing, and in between
* space will be erase.
* @param char* source
* @return char* result1
*/
char* eraseWhite(char* source)
{
if(!source)
return NULL;
int
lenStr = strlen(source);
int
count = 0;
char
result[lenStr];
for(int
i=0;i<lenStr;i++)
if(source[i] !=' ')
result[count++]=source[i];
result[count]='\0';
char*
result1 = strdup(result);
return
result1;
}