가위바위보 게임(클라이언트대 클라이언트)???
글쓴이: namola / 작성시간: 목, 2003/12/04 - 8:59오전
가위바위보 게임(클라이언트대 클라이언트)을
구현해 보았는데...처음 각각 2개의 클라이언트가
접속하여 게임을 하면...잘돼는데..그리고 종료가
된다음에 다시 접속하게 되면...잘 안됩니다.
이유가 무엇일까요?
답변 부탁드리겠습니다.
다음은 서버 코드 입니다.
/*
* ipcgame_serv.c
* Written by CH. Yoo
*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include
#include
#include
#include
#define BUFSIZE 100
void error_handling(char *message);
void z_handler(int sig);
int who_win(int a,int b);
int main(int argc, char **argv)
{
int fd1[2],fd2[2];
char buffer[BUFSIZE];
char intro[]="입력하세요(가위:0 바위:1 보:2) : ";
/* 바이트 비교시 48,49,50 */
char win[]="축하합니다. 당신이 이겼습니다.\n";
char lose[]="안타깝게도 졌네요.\n";
char no_winner[]="비겼네요. 승자가 없습니다. \n";
int serv_sock;
int clnt_sock;
struct sockaddr_in serv_addr;
struct sockaddr_in clnt_addr;
struct sigaction act;
int str_len, state, addr_size,clnt_num;/*clnt_num 추가*/
pid_t pid;
if(argc!=2) {
printf("Usage : %s \n", argv[0]);
exit(1);
}
if(pipe(fd1)==-1||pipe(fd2)==-1)/*두개의 파이프 생성*/
error_handling("pipe() error");
act.sa_handler=z_handler;/*시그널 핸들링을 위한 핸들러 설정*/
sigemptyset(&act.sa_mask);
act.sa_flags=0;
state=sigaction(SIGCHLD, &act, 0);/*시그널 핸들러 등록*/
if(state==-1)
error_handling("sigaction() error");
serv_sock=socket(PF_INET,SOCK_STREAM,0);
if(serv_sock==-1)
error_handling("socket() error");
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_addr.sin_port=htons(atoi(argv[1]));
if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr))==-1)
error_handling("bind() error");
if(listen(serv_sock,5)==-1)
error_handling("listen() error");
clnt_num=0;/*0으로 초기화*/
while(1) {
addr_size=sizeof(clnt_addr);
clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&addr_size);
if(clnt_sock==-1)
continue;
if( (pid=fork()) == -1) { /*fork 실패시*/
close(clnt_sock);
continue;
}
else if (pid > 0) { /*부모프로세스 실행 영역*/
int result;
puts("연결 생성");
close(clnt_sock);
if(clnt_num==0) {
clnt_num++;
continue;
}
read(fd1[0],&buffer[0],BUFSIZE-1);/*첫번째 클라이언트 수신*/
read(fd1[0],&buffer[1],BUFSIZE-1);/*두번째 클라이언트 수신*/
result = who_win(buffer[0],buffer[1]);
if(result==0) { /*비긴경우*/
buffer[2]=0;
buffer[3]=0;
buffer[4]=0;
write(fd2[1],buffer,sizeof(buffer));
write(fd2[1],buffer,sizeof(buffer));
}
else if (result == 1) { /* 이긴경우 */
buffer[2]=1;
buffer[3]=-1;
buffer[4]=0;
write(fd2[1],buffer,sizeof(buffer));
write(fd2[1],buffer,sizeof(buffer));
}
else { /* 진경우*/
buffer[2]=-1;
buffer[3]=1;
buffer[4]=0;
write(fd2[1],buffer,sizeof(buffer));
write(fd2[1],buffer,sizeof(buffer));
}
}
else { /* chlid process zone */
close(serv_sock);
char temp;
write(clnt_sock,intro,sizeof(intro));
read(clnt_sock,buffer,BUFSIZE); /*클라이언트 선택 수신*/
write(fd1[1],buffer,1);/*부모프로세스로 선택 전송*/
temp=buffer[0];
read(fd2[0],buffer,BUFSIZE);
temp = (temp==buffer[0]) ? buffer[2] : buffer[3];
if(temp==0)
write(clnt_sock,no_winner,sizeof(no_winner));
else if (temp==1)
write(clnt_sock,win,sizeof(win));
else
write(clnt_sock,lose,sizeof(lose));
puts("연결 종료");
close(clnt_sock);
clnt_num--;
exit(0);
}
}
return 0;
}
void z_handler(int sig)
{
pid_t pid;
int rtn;
pid=waitpid(-1,&rtn,WNOHANG);
printf("소멸된 좀비의 프로세스 ID : %d \n", pid);
printf("리턴된 데이터 : %d \n\n", WEXITSTATUS(rtn));
}
int who_win(int a, int b)
{
if(a==b)
return 0;
else if(a%3==(b+1)%3)
return 1;
else
return -1;
}
void error_handling(char *message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit(1);
} 다음은 클라이언트 코드입니다.
#include <stdio.h>
#include <unistd.h>
#include
#include
#include
#define BUFSIZE 100
void error_handling(char *message);
int main(int argc, char **argv)
{
int sock;
char message[BUFSIZE];
int str_len;
struct sockaddr_in serv_addr;
if(argc!=3) {
printf("Usage : %s \n", argv[0]);
exit(1);
}
sock=socket(PF_INET,SOCK_STREAM,0);
if(sock==-1)
error_handling("socket() error");
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=inet_addr(argv[1]);
serv_addr.sin_port=htons(atoi(argv[2]));
if(connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr))==-1)
error_handling("connect() error");
/* 가위,바위,보 game start */
str_len=read(sock,message,BUFSIZE-1);
message[str_len]=0;
fputs(message,stdout);
fflush(stdout);
str_len=read(0,message,BUFSIZE);
write(sock,message,str_len);
str_len=read(sock,message,BUFSIZE-1);
message[BUFSIZE]=0;
puts(message);
close(sock);
return 0;
}
void error_handling(char *message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit(1);
}Forums:


댓글 달기