가위바위보 게임(클라이언트대 클라이언트)???
글쓴이: 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:
댓글 달기