채팅서버 fifo방식 문제...
글쓴이: zzzalxl / 작성시간: 금, 2012/12/14 - 12:26오후
채팅서버를 fifo방식을 써서 구현했는데 서버창하나 클라이언트창 두개로해서
각 클라이언트끼리 채팅을 주고받는 것을 구현해서 성공했습니다.
근데 한쪽은 주고 한쪽은 받고만 하는거라 이 방식을 양쪽다 주고받고를 동시에
실시간으루 구현하려고 하는데 도무지 감이 안잡혀서요...
고수님들 답변 바랍니다.
/*
* echo_serv
* test
*/
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <signal.h> #include <sys/sem.h> #include <sys/wait.h> #include <time.h> #include <malloc.h> #include <sys/ipc.h> #include "echo_serv.h" #define INITCHER(x) memset(x, 0x00, sizeof(x)) #define BUFSIZE 1024 #define FIFO_GET "fifo1" #define FIFO_SEND "fifo2" /* #define _DEBUG_ */ EXEC SQL INCLUDE SQLCA; void RemoveHeadTail(char *str); void error(char *message); void z_handler(int sig); int echo_serv(int clnt_sock); int main() { int serv_sock; int clnt_sock; int str_len; pid_t pid; struct sockaddr_in servaddr; struct sockaddr_in clntaddr; int clntlen; char buff[1000]; struct sigaction act; act.sa_handler = z_handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; Connect_Olacle(); demon_d(); sigaction(SIGCHLD, &act, 0); serv_sock = socket(PF_INET, SOCK_STREAM,0); if(serv_sock==-1) error("socket() error"); memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); servaddr.sin_port=htons(9990); if(bind(serv_sock,(struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){ fprintf(stderr, "server: can't bind local address\n"); close(serv_sock); exit(-1); } if(listen(serv_sock,5)==-1){ error("listen() error"); } printf("채팅 접속 대기중\n"); for(;;){ clntlen = sizeof(clntaddr); clnt_sock=accept(serv_sock,(struct sockaddr*)&clntaddr,&clntlen); if(serv_sock == -1){ error("accept() error"); } /* if(str_len=read(clnt_sock,buff, sizeof(buff)) == 0){ return(0); }*/ fflush(stdout); pid = fork(); if (pid < 0){ printf("fork error"); close(clnt_sock); continue; }else if(pid == 0){ close(serv_sock); echo_serv(clnt_sock); close(clnt_sock) ; return(0); }else{ close(clnt_sock) ; } } Commit_Olacle(); close(clnt_sock); return(0); } int demon_d() { pid_t pid; if((pid = fork()) < 0){ return(-1); }else if(pid != 0){ exit(0); } setsid(); umask(0); return(0); } void error(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); } void z_handler(int sig) { pid_t pid; int rtn; pid=waitpid(-1, &rtn, WNOHANG); } int Connect_Olacle(void) { EXEC SQL BEGIN DECLARE SECTION; char uname[20]; char pw[20]; EXEC SQL END DECLARE SECTION; INITCHER(uname); INITCHER(pw); strcpy(uname,"zipcode"); strcpy(pw,"zipcode"); EXEC SQL CONNECT :uname IDENTIFIED BY :pw; if(sqlca.sqlcode != 0){ printf(" DB 접속 에러!", sqlca.sqlcode); return(1); }else{ printf("채팅DB접속\n"); } return(0); } int Commit_Olacle(void) { EXEC SQL COMMIT WORK RELEASE; printf("DB 접속 종료! 수고하셨습니다!\n"); return(0); }
int echo_serv(int clnt_sock) { EXEC SQL BEGIN DECLARE SECTION; char *a,*b,*id,*p,*p2,*p3; typedef struct{ char id[15]; char id2[15]; char pw[20]; char flag[10]; char message[BUFSIZE]; } ServStruct; ServStruct *arr1; ServStruct *arr2; EXEC SQL END DECLARE SECTION; time_t s_time; char ch[BUFSIZE]; int str_len1,str_len2; int i,j; int cmp; int fd,fd1; char fff[10]; char buff[1000]; /*처음 로그인*/ char *login = "1"; /* 3회 오류 */ char *pw3 = "2"; /*신규 유저*/ char *new_user = "3"; /*암호 수정*/ char *pwchange = "4"; /*로그인 상태*/ char *logon = "5"; char *logout = "6"; int sss=0; typedef struct{ long data_type; char to_id[15]; char data_buff[100]; } t_data; int mspid; int ndx =0; t_data *data; int pipe_get[2]; int pipe_send[2]; data = (t_data*) malloc( sizeof(t_data)); arr1 = (ServStruct*) malloc( sizeof(ServStruct)); /*malloc 사용*/ arr2 = (ServStruct*) malloc( sizeof(ServStruct));
while(str_len2=read(clnt_sock,buff, sizeof(buff)) != 0){ /*로그인 과정*/ /*플래그의 상태를 확인하여 최초 로그인, 3회 오류, 신규가입, 암호변경을 확인*/
memset(arr1, 0x00, sizeof(ServStruct));
memset(arr2, 0x00, sizeof(ServStruct));
printf("[%s]\n",buff);
p = strtok(buff,"|");
p2 = strtok(NULL,"|");
p3 = strtok(NULL,"|");
strcpy(arr2->id,p);
strcpy(arr2->pw,p2);
strcpy(arr2->flag,p3);
/*신규가입 플래그가 들어왔을시 DB에 신규 INSERT*/
if(!strcmp(arr2->flag,new_user)){
EXEC SQL SELECT I INTO :arr1->id
FROM LOG_DATA
WHERE I = :arr2->id;
EXEC SQL COMMIT;
RemoveHeadTail(arr1->id);
/*검색하여 기존에 있는 사용자인지 확인, 기존 유저가 있으면 플래그를 클라이언트로 보냄*/
if(!strcmp(arr1->id,arr2->id)){
printf("존재하는 아이디 입니다.\n");
strcpy(buff,"uu");
write(clnt_sock, buff, sizeof(buff));
}else{
EXEC SQL INSERT INTO LOG_DATA(I, P, F)
VALUES(:arr2->id, :arr2->pw, :arr2->flag);
EXEC SQL COMMIT;
strcpy(arr1->id,arr2->id);
break;
}
/* }else if(strcmp(arr2->flag,login)){
EXEC SQL SELECT I INTO :arr1->id
FROM LOG_DATA
WHERE I = :arr2->id; */
/*전회에 3회 오류시 플래그를 클라이언트로 보냄*/
}else if(!strcmp(arr2->flag,pw3)){
printf("pw 3번 오류\n");
EXEC SQL UPDATE LOG_DATA
SET F = :arr2->flag
WHERE I = :arr2->id;
EXEC SQL COMMIT;
/*암호 수정을 받는 부분*/
}else if(!strcmp(arr2->flag,pwchange)){
strcpy(arr2->flag,logon);
EXEC SQL UPDATE LOG_DATA
SET P =:arr2->pw, F =:arr2->flag
WHERE I =:arr2->id;
EXEC SQL COMMIT;
break;
}
/*클라이언트로 부터 아이디 암호를 받아서 유저 테이블을 검색*/
EXEC SQL SELECT I,P,F
INTO :arr1->id, :arr1->pw, :arr1->flag
FROM LOG_DATA
WHERE I = :arr2->id;
EXEC SQL COMMIT;
RemoveHeadTail(arr1->id);
RemoveHeadTail(arr1->pw);
RemoveHeadTail(arr1->flag);
printf("[%s]\n",arr1->id);
/*입력받은 아이디가 유저 테이블에 없을시 플래그를 클라이언트로 보냄*/
if(strcmp(arr1->id,arr2->id)){
printf("ID를 찾지 못했습니다.\n");
strcpy(buff,"i");
write(clnt_sock, buff, sizeof(buff));
memset(buff, 0x00, sizeof(buff));
/*입력받은 암호가 검색 결과와 다를시 플래그를 클라이언트로 보냄*/
}else if(strcmp(arr1->pw,arr2->pw)){
printf("암호가 틀렸습니다.\n");
strcpy(buff,"p");
write(clnt_sock, buff, sizeof(buff));
memset(buff, 0x00, sizeof(buff)) ;
/*검색한 플래그가 3회 오류 상태였을시 플래그 보냄*/
}else if(!strcmp(arr1->flag,pwchange)){
printf("전회 암호 3번 오류, 수정 요망\n");
strcpy(buff,"x");
write(clnt_sock, buff, sizeof(buff));
memset(buff, 0x00, sizeof(buff)) ;
}else{
strcpy(buff,"fff");
write(clnt_sock,arr1->message, str_len2);
break;
}
}
EXEC SQL UPDATE LOG_DATA
SET F = :arr2->flag
WHERE I = :arr1->id;
EXEC SQL COMMIT;
printf("접속완료...\n");
if(mkfifo(FIFO_GET, 0666)==-1){ /*fifo생성함수써서 생성*/
printf("wait....\n");
}
if((fd =open(FIFO_GET, O_RDWR))==-1){ /*오픈하고 파일 디스크립터를 리턴*/
printf("wait...\n");
}
read(clnt_sock,ch, sizeof(buff));
#ifdef _DEBUG_
printf("[%s]\n",buff);
#endif
while(1){
if(!strcmp(ch,"1")){
printf("[%s]님이 메세지 입력중...\n",arr2->id);
read(clnt_sock,buff, sizeof(buff));
p = strtok(buff,"|");
p2 = strtok(NULL,"|");
p3 = strtok(NULL,"|");
strcpy(arr2->id2,p);
strcpy(arr2->message,p2);
strcpy(arr2->flag,p3);
#ifdef _DEBUG_
printf("[%s],[%s],[%s]\n",arr2->id2,arr2->message,arr2->flag);
#endif
EXEC SQL SELECT I,F
INTO :arr1->id2,:arr1->flag
FROM LOG_DATA
WHERE I = :arr2->id2;
EXEC SQL COMMIT;
RemoveHeadTail(arr1->id2);
RemoveHeadTail(arr1->flag);
RemoveHeadTail(ctime(&s_time));
#ifdef _DEBUG_
printf("[%s],[%s]\n",arr1->id2,arr2->id2);
#endif
/* if(strcmp(arr1->id2,arr2->id2)){
printf("없는 ID입니다.\n");
memset(buff,0x00,sizeof(buff));
strcpy(arr2->flag,"NU");
sprintf(buff,"%s|%s|%s|",arr1->id,arr2->message,arr2->flag);
write(clnt_sock, buff, sizeof(buff));
}else if(strcmp(arr1->flag,login)){
printf("없는 user ID\n");
memset(buff,0x00,sizeof(buff));
strcpy(buff,"NU");
write(clnt_sock, buff, sizeof(buff));
}else{ */
memset(buff, 0x00, sizeof(buff)) ;
write(clnt_sock, buff, sizeof(buff));
time(&s_time);
printf("=======================\n");
printf("-수신ID :[%s]\n",arr2->id2);
printf("-요청시간 :[%s]\n",ctime(&s_time));
printf("-요청 메세지 : [%s]\n",arr2->message);
printf("=======================\n");
EXEC SQL INSERT INTO CHAT_DATA(I,I2,T,A)
VALUES(:arr1->id,:arr2->id2, SYSDATE, :arr2->message);
EXEC SQL COMMIT;
sprintf(buff,"%s|%s|%s|",arr1->id,arr2->message,arr2->id2);
#ifdef _DEBUG_
printf("송신[%s]\n",buff);
#endif
write(fd, buff, sizeof(buff));
#ifdef _DEBUG_
printf("송신 ID[%s]\n",arr1->id);
#endif
memset(buff, 0x00, sizeof(buff)) ;
strcpy(ch,"2");
}else if(!strcmp(ch,"2")){
while(1){
printf("[%s]수신모드 입니다.\n",arr2->id);
memset(buff, 0x00, sizeof(buff)) ;
read(fd, buff, sizeof(buff));
#ifdef _DEBUG
printf("수신[%s]\n",buff);
#endif
p = strtok(buff,"|");
p2 = strtok(NULL,"|");
p3 = strtok(NULL,"|");
strcpy(arr2->id2,p);
strcpy(arr2->message,p2);
strcpy(arr2->id,p3);
#ifdef _DEBUG_
printf("[%s],[%s]\n",arr1->id,arr2->id);
#endif
if(!strcmp(arr1->id,arr2->id)){
#ifdef _DEBUG_
printf("334567\n");
#endif
EXEC SQL INSERT INTO CHAT_DATA(I,I2,T,B)
VALUES(:arr1->id,:arr2->id2, SYSDATE, :arr2->message);
EXEC SQL COMMIT;
sprintf(buff,"%s|%s|%s",arr2->id2,arr2->message,arr2->flag);
#ifdef _DEBUG_
printf("[%s]\n",buff);
#endif
write(clnt_sock,buff,sizeof(buff));
memset(buff, 0x00, sizeof(buff)) ;
strcpy(ch,"1");
break;
}
}
}
}
free(arr1);
free(arr2);
}
Forums:
이거 참고 해보세요.
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
댓글 달기