/**
* Group : Edison Chindrawaly
*
Sehoon Jung
* Sangtae Park
*
* Project: #2 Game Server
*/
#include "game_server.h"
struct
test
{
int pid;
char name[MAXSIZE];
} TEST;
void
main()
{
int listenfd;
listenfd = openConnection(7778);
beginProcess(listenfd);
closeConnection(listenfd);
}
/**
* openConnection's method is to establish
connection
* between the client
and host.
* @param int PORT contains predefine port
number
* @return sockfd if flag ==
1 else connfd is return
*/
int
openConnection(int PORT)
{
int servsize;
int yes
= 1;
int
sockfd,connfd,clientsize;
struct
sockaddr_in my_add;
struct
sockaddr_in other_add;
sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
verify(0,sockfd,socket_flag);
bzero(&(my_add.sin_zero),sizeof(my_add));
my_add.sin_family = AF_INET;
my_add.sin_port = htons(PORT);
my_add.sin_addr.s_addr = INADDR_ANY;
verify(sockfd,
bind(sockfd,(struct
sockaddr *)&my_add, sizeof(struct sockaddr)),
bind_flag);
verify(sockfd,listen(sockfd,BACKLOG),listen_flag);
return sockfd;
}
/**
* beginProcess's method is where the process
is being
* execute - send/receive
messages. It receives a listen socket
* descriptors. It accepts more than 2 connections from 2 or
* more clients. Right now I specify the max
number of client
* to be 5
clients.
* @param int sockfd1 contains TCP socket
descriptor
* @return none
*/
void beginProcess(int sockfd)
{
int fd[2];
int flag = 0;
int win
= 0; // contains the flag for
winner
int random[3]; // contains
generated random number
int
pid_temp, pid_child;
char
temp[MAXSIZE];
printf("Generate number: ");
for(int i=0; i<3; i++)
{
random[i] = generateNumber((rand()+i)%10);
printf("%i ", random[i]);
}
printf("\n");
//for networking purposes
int new_sock = 0;
int
byteRecv = 0;
int byteSend =
0;
struct sockaddr_in
other_add;
int clisize =
sizeof(other_add);
//prepare
the set for select()
fd_set
master;
fd_set read_fds;
//clean the select() set
FD_ZERO(&master);
FD_ZERO(&read_fds);
//add sockfd to master set for listening
FD_SET(sockfd, &master);
FD_SET(STDIN, &master);
FD_SET(fd[READ],&master);
//initialize struct
MESSAGE msg;
STORAGE *store;
//messages
char*
greet_msg = "You are connected to game server";
char* win_msg = "One of the players have
guess the number. Game is over";
char* ply_msg = "You have win the game!
Congratulation";
printf("Press any key to
terminate\n");
while(true)
{
read_fds = master;
verify(sockfd,
select(FD_SETSIZE,&read_fds,NULL,NULL,NULL),
select_flag);
if(FD_ISSET(STDIN,&read_fds))
{
printf("game_server terminates\n");
break;
} // end for detecting keyboard
if(FD_ISSET(sockfd,&read_fds))
{
new_sock =
accept(sockfd,
(struct sockaddr
*)&other_add,
(socklen_t *)&clisize);
printf("Receive connection from %s\n",
inet_ntoa(other_add.sin_addr));
verify(new_sock, pipe(fd), pipe_flag);
//child process
if(fork() == 0)
{
close(sockfd);
pid_child = getpid();
flag = 1;
msg.flag = 1;
strcpy(msg.message,greet_msg);
verify(new_sock,sendStruct(new_sock,msg),send_flag);
verify(new_sock,receivedStruct(new_sock,msg),receive_flag);
printf("user name: %s\n",msg.name);
verify(new_sock,
write(fd[WRITE],&flag,sizeof(flag)),
write_flag);
verify(new_sock,
write(fd[WRITE],&pid_child,sizeof(int)),
write_flag);
verify(new_sock,
write(fd[WRITE],&(msg.message),sizeof(msg.message)),
write_flag);
//FD_SET(new_sock,&read_fds);
printf("successfully set
new_sock\n");
while(true)
{
printf("before
select\n");
//verify(new_sock,
//select(FD_SETSIZE,&read_fds,NULL,NULL,NULL),
//select_flag);
if(FD_ISSET(new_sock,&read_fds))
//receive from client
{
printf("receive something from
client\n");
byteRecv =
receivedStruct(new_sock,msg);
verify(new_sock,byteRecv,receive_flag);
switch(msg.flag)
{
case 0: win =
checkGuess(random,msg);
if(win == 1)
{
(*store).win = 1;
verify(0,write(fd[WRITE],(char *)&store,sizeof(store)),
write_flag);
strcpy(msg.message,win_msg);
msg.flag = 1;
byteSend =
sendStruct(new_sock,msg);
}
else
{
msg.flag = 0;
byteSend = sendStruct
(new_sock,msg);
}
verify(new_sock,byteSend,send_flag);
break;
case 1: if(strcasecmp(msg.message,"END") ==0)
{
(*store).end = 1;
verify(0,write(fd[WRITE],(char
*)&store,sizeof(store)),
write_flag);
break;
}
printf("client send:
%s\n",msg.message);
break;
case 2:
verify(0,write(fd[WRITE],(char *)&msg,sizeof(msg)),
write_flag);
}
}
if(FD_ISSET(fd[READ],&read_fds)) //receive from parent
{
printf("receive something from parent\n");
verify(0,read(fd[READ],(char
*)&msg,sizeof(msg)),read_flag);
printf("receive : %s\n",msg.message);
}
printf("do not get it\n");
}
close(new_sock);
exit(0);
} // end of
child
close(new_sock);
//parent
if(FD_ISSET(fd[READ],&read_fds))
{
verify(sockfd,read(fd[READ],&flag,sizeof(flag)),read_flag);
if(flag == 1)
{
verify(sockfd,read(fd[READ],&pid_temp,sizeof(int)),read_flag);
verify(sockfd,read(fd[READ],&temp,sizeof(temp)),read_flag);
(*store).pid = pid_temp;
strcpy((*store).player_name,temp);
printf("receive from child
%i\n",pid_temp);
*store++;
}
} // end for parent
} // end for detecting a new request for
socket
} // end of while
loop
} // end of beginProcess
/**
* checkGuess' method is to check the guess of
the player with
* the assign
random number generated by the system. It also
* written to the result of the user guess into the MESSAGE
struct
* which is going to be
return to user.
* @param int[] array contains the generated number by
the system
* MESSAGE& msg contains the user
guess
* @return int 1 if guess is
all correct else return 0
*/
int
checkGuess(int array[], MESSAGE& msg)
{
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
if(array[i] == msg.guess[j])
if(i == j) // check the position
msg.result[i] = strike;
else
msg.result[i] = ball;
if(msg.result[1] == strike)
if(msg.result[2] == strike)
if(msg.result[3] == strike)
return 1; // all the guesses is correct
return 0;
}
/**
*
verify's method is to verify the success of the operation.
* if the operation fails, it will terminate
the whole program.
* @param int sockfd contains socket descriptor if
available
* int byte contains the byte receives
from the operation
* int flag contains the description of the
flag
* @return none
*/
void verify(int sockfd, int byte, int
flag)
{
switch(flag)
{
case 0:if(byte<0)
{
perror("ERROR: socket has failed\n");
exit(0);
}
break;
case
1:if(byte<0)
{
perror("ERROR: bind has failed\n");
closeConnection(sockfd);
exit(0);
}
break;
case
2:if(byte<0)
{
perror("ERROR: listen has
failed\n");
closeConnection(sockfd);
exit(0);
}
break;
case 3:if(byte<0)
{
perror("ERROR: accept has failed\n");
closeConnection(sockfd);
exit(0);
}
break;
case
4:if(byte<0)
{
perror("ERROR: send has
failed\n");
closeConnection(sockfd);
exit(0);
}
break;
case 5:if(byte<0)
{
perror("ERROR: receive has failed\n");
closeConnection(sockfd);
exit(0);
}
break;
case 6:if(byte<0)
{
perror("ERROR: pipe has failed\n");
exit(0);
}
break;
case
7:if(byte<0)
{
perror("ERROR: write has
failed\n");
exit(0);
}
break;
case 8:if(byte<0)
{
perror("ERROR: read has failed\n");
exit(0);
}
break;
case
9:if(byte<0)
{
perror("ERROR: select has
failed\n");
exit(0);
}
default: break;
}
}
/**
* generateNumber's method is to generate
random number
* @param int number contains the number given by
program
* @return int random
number 1 digit long
*/
int
generateNumber(int num)
{
time_t timer;
srand((unsigned)time(&timer));
return ((rand() * (num+1))
% 10);
}
/**
*
receivedStruct's method is to receive struct from
* the given socket. It will return -1 if it
fails
* to receive otherwise it
will return int bigger than
*
zero.
* @param int sockfd contains sock descriptor
*
struct MSG contains the struct itself
* @return int
*/
int receivedStruct(int sockfd, MESSAGE&
receivedMsg)
{
int byteRecv
= 0;
byteRecv = recv(sockfd,(char
*)&receivedMsg,sizeof(MESSAGE),0);
return byteRecv;
}
/**
* sendStruct's method is to send MESSAGE struct to the
client/
* server that is address
by the socket descriptor
*
@param int sockfd contains socket
descriptor
* MESSAGE msg contains the message
struct
* @return -1 if fail
otherwiser return number of bytes send
*/
int sendStruct(int sockfd, MESSAGE msg)
{
int numSend = 0;
numSend = send(sockfd,(char *)&msg,
sizeof(MESSAGE),0);
return
numSend;
}
/**
* closeConnection's method is to close the socket
* descriptor that contains the connection of
* the client/server's model
* @param
int sockfd contains socket descriptor
* @return none
*/
void closeConnection(int sockfd)
{
close(sockfd);
}