c언어 tcp소켓 코딩 좀 알려주세요...
조건)유닉스 클라끼리 실시간 채팅하는 프로그램인데
멀티프로세스방식과 fork문을 써서
table1에다가 회원가입된 id, pw, 접속확인을 담고
table2에다가 채팅중인 id1, id2, date, 채팅내용을
담아야됩니다.
그리고 서버 접속시 회원가입과 로그인을 담아
pw는 10자리미만이면 오류, 영어숫자조합 대소문자구분X
3회오류시에 클라 종료되고, 다시 이 아이디로 접속시 3회오류
pw변경을하라는 정보를 담아야됩니다.
중요한건 클라끼리 실시간으로 채팅을 해야한다는건데
너무 어렵습니다..도움좀 주세요
(server)
/*
* echo_serv.c
* test
*/
#include
#include
#include
#include /* close(), write(), read() */
#include /* socket(), bind(), listen(), accept(), connect() */
#include /* */
#include /* open() */
#include
#include
#include
#include
#include
#include
#include
#define INITCHAR(x) memset(x,0x00,sizeof(x))
#define PORT 2100 /* 포트 번호 고정 */
#define BUFSIZE 1024
EXEC SQL INCLUDE SQLCA;
void error_handling(char *message);
void z_handler(int sig);
int echo_serv(int clnt_sock);
int main(int argc, char **argv)
{
int clnt_len;
int serv_sock;
int clnt_sock;
struct sockaddr_in serv_addr;
struct sockaddr_in clnt_addr;
time_t s_time;
char a[100],b[100];
int addr_size, str_len, state;
pid_t pid;
char message[BUFSIZE];
struct sigaction act;
act.sa_handler=z_handler;
sigemptyset(&act.sa_mask);
act.sa_flags=0;
Connect_Oracle();
daemon_init(); /* 데몬 */
state=sigaction(SIGCHLD, &act, 0); /* 시그널 핸들러 등록 */
if(state != 0){
puts("sigaction() error");
exit(1);
}
serv_sock=socket(PF_INET, SOCK_STREAM, 0);
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(PORT);
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");
for(;;){
clnt_len = sizeof(clnt_addr);
clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_len);
if(serv_sock == -1){
error_handling("accept() error");
}
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);
printf("!!!연결 종료!!!\n");
close(clnt_sock);
return(0);
}else{ /* 자식 프로세스의 경우 */
close(clnt_sock) ;
}
}
Commit_Oracle();
close(clnt_sock);
return(0);
}
int daemon_init()
{
pid_t pid;
if((pid = fork()) < 0)
return(-1);
else if(pid != 0)
exit(0); /* 부모프로세스는 종료시킨다 */
/* child continues */
setsid(); /* 스스로 세션의 리더가 된다 */
umask(0); /* clear our file mode creation mask */
return(0);
}
void error_handling(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);
printf("소멸된 좀비의 프로세스 ID : %d \n", pid);
printf("리턴된 데이터 : %d \n\n", WEXITSTATUS(rtn));
}
int Connect_Oracle(void)
{
EXEC SQL BEGIN DECLARE SECTION;
char uname[20];
char passwd[20];
EXEC SQL END DECLARE SECTION;
INITCHAR(uname);
INITCHAR(passwd);
strcpy(uname,"zipcode");
strcpy(passwd,"zipcode");
EXEC SQL CONNECT :uname IDENTIFIED BY :passwd;
if(sqlca.sqlcode != 0){
printf(" DB CONNECT ERROR \n", sqlca.sqlcode);
return(1);
}else{
printf(" DB CONNECT SUCCESS \n");
}
return(0);
}
int Commit_Oracle(void)
{
EXEC SQL COMMIT WORK RELEASE;
printf("DB 접속 종료\n");
return(0);
}
int echo_serv(int clnt_sock)
{
EXEC SQL BEGIN DECLARE SECTION;
char ch[BUFSIZE];
int str_len1;
time_t s_time;
char *id,*id2,*a,*b,*s,*s1;
EXEC SQL END DECLARE SECTION;
struct eservstruct{
char id[20];
char id2[20];
char pw[20];
char message[BUFSIZE];
};
char buff[1000];
struct eservstruct *i;
i = (struct eservstruct*) malloc( sizeof(struct eservstruct));
memset(i, 0x00, sizeof(struct eservstruct));
/* 자식 프로세스의 처리 영역: 데이터 수신 및 전송 */
while(str_len1=read(clnt_sock,buff, sizeof(buff)) != 0){
s = strtok(buff,"|");
s1 = strtok(NULL,"|");
strcpy(i->id,s);
strcpy(i->message,s1);
time(&s_time);
printf("접속중인 ID : [%s]\n", i->id);
printf("메시지 수신시간 : %s", ctime(&s_time));
/*printf("[%s]\n",message);*/
printf("입력받은 메시지 : %s\n",i->message);
printf("전달할 메시지 : %s\n\n",i->message);
EXEC SQL INSERT INTO ECHO_SERV(I,T,A,B)
VALUES(:i->id, SYSDATE, :i->message, :i->message);
EXEC SQL COMMIT;
write(clnt_sock,i->message, str_len1);
memset(buff, 0x00, sizeof(buff));
}
free(i);
}
(client)
#include
#include
#include
#include
#include
#include
#include
#include /* 문자 함수 */
#define BUFSIZE 1024
#define PORT 2100
void error_handling(char *message);
int join(int *new_num, char *id, char *pw);
int main(int argc, char **argv)
{
int *num;
char isalpha, isdigit;/* 영숫자 */
int k=0;
int a,n = 0;
int i=0;
char *id1;
char *pw1;
char new_check[10];
int new_num;
char *pw3;
int pwcnt=0;
char message[BUFSIZE];
int sock;
pid_t pid;
int str_len, recv_len, recv_num;
struct sockaddr_in serv_addr;
char buff[1000];
typedef struct{
char id[20];
char pw[20];
char message[BUFSIZE];
char flag[100];
}clntstruct;
sock=socket(PF_INET, SOCK_STREAM, 0);
clntstruct *j;
j = malloc(sizeof(clntstruct));
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
serv_addr.sin_port=htons(PORT);
if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1){
error_handling("connect() error!");
}
while(1){
input : printf("[1]회원가입 [2]로그인\n");
scanf("%d",&k);
if(k==1){/* 회원가입 */
printf("New ID : ");
scanf("%s",j->id);
printf("New PW : ");
scanf("%s",j->pw);
while(strlen(gets(j->pw))<10){ /* pw 10자리 미만 오류 */
printf("PW ERROR\n");
memset(j->pw, 0x00, sizeof(j->pw));
printf("New PW : ");
}
/* if(isdigit(j->pw)) && (isalpha(j->pw)){ /* 영,숫자만 한글 오류*/
/* printf("PW ERROR\n");
memset(j->pw, 0x00, sizeof(j->pw));
return(0);
} */
/* printf("pw : "); */
goto input;
}
else if(k==2){ /* 로그인 */
printf("ID : ");
scanf("%s",j->id);
printf("PW : ");
scanf("%s",j->pw);
while(strlen(gets(j->id))>20){
printf("ID ERROR\n");
memset(j->id, 0x00, sizeof(j->id));
printf("ID : ");
}
while(strlen(gets(j->pw))<10){ /* pw 10자리 미만 오류 */
printf("PW ERROR\n");
memset(j->pw, 0x00, sizeof(j->pw));
printf("PW : ");
}
while(1){ /* 3회 오류 */
// printf("PW ERROR\n");
pwcnt++;
memset(buff,0x00,sizeof(buff));
if(pwcnt == 3){
strcpy(j->flag,pw3);
sprintf(buff,"%s|%s|%s",j->id,j->pw,j->flag);
write(sock, buff, sizeof(buff));
printf("PW 3 ERROR\n");
return(0);
}
// memset(j->pw, 0x00, sizeof(j->pw));
// printf("PW : ");
sprintf(buff,"%s|%s|%s|",j->id,j->pw,j->flag);
write(sock, buff, sizeof(buff));
memset(buff,0x00,sizeof(buff));
read(sock, buff, sizeof(buff));
if(strcmp(buff,"p")){
break;
}
}
/* strcpy(id1,id);
strcpy(pw1,pw); */
goto end;
}
end : printf("채팅접속!!\n");
while(1){
fflush(stdin);
printf("전송할 메시지를 입력하세요 (q,Q to quit) : ");
if(strlen(gets(j->message))>BUFSIZE){
printf("error");
break;
}
if(!strcmp(j->message,"q")){
break;
}else if(!strcmp(j->message,"Q")){
break;
}
strcpy(buff,j->id);
strcat(buff,"|");
strcat(buff,j->message);
strcat(buff,"|");
str_len=write(sock, buff, sizeof(buff));
str_len = read(sock, j->message, sizeof(j->message));
printf("서버로부터 전송된 메시지 : %s\n",j->message);
memset(j->message,0x00,sizeof(j->message));
}
free(j);
printf("CLIENT EXIT!!\n");
close(sock);
return(0);
}
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
댓글 달기