c언어 tcp소켓 코딩 좀 알려주세요...

zzzalxl의 이미지

조건)유닉스 클라끼리 실시간 채팅하는 프로그램인데
멀티프로세스방식과 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);
}

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.