채팅서버 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
댓글 달기