/* ipcgame_serv.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>

#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;
  pid_t pid;

  if(argc!=2){
    printf("Usage : %s <port>\n", argv[0]);
    exit(1);
  }

  if(pipe(fd1)<0 || pipe(fd2)<0) /* 프로세스 양 방향 통신 위한 파이프 생성 */
    error_handling("pipe() error");

  act.sa_handler=z_handler; /* 시그널 핸들링을 위한 핸들러 설정 */
  sigemptyset(&act.sa_mask);
  act.sa_flags=0;

  state=sigaction(SIGCHLD, &act, 0); /* 시그널 핸들러 등록 */
  if(state != 0)
    error_handling("sigaction() error")
 
  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(atoi(argv[1]));

  if( bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) )
    error_handling("bind() error");
  if( listen(serv_sock, 5))
    error_handling("listen() error");

  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);

      /* 이제부터 게임 시작 */
      write(1, intro, sizeof(intro));
      read(0, buffer, BUFSIZE);                 /* 서버로부터 선택(가위 바위 보) 수신 */
      read(fd1[0], &buffer[1], BUFSIZE-1);      /* 자식 프로세스로부터 클라이언트 선택 수신 */
     
      result = who_win(buffer[0], buffer[1]); /* 승자를 가린다 */
      if(result==0){     /* 비긴 경우 */
  write(1, no_winner, sizeof(no_winner));
  write(fd2[1], no_winner, sizeof(no_winner));
      }
      else if( result == 1){   /* 서버가 이긴 경우 */
  write(1, win, sizeof(win));
  write(fd2[1], lose, sizeof(lose));
      }
      else{        /* 클라이언트가 이긴 경우 */
  write(1, lose, sizeof(lose));
  write(fd2[1], win, sizeof(win));
      }
    }
    else {                  /* 자식 프로세스 실행 영역 */
      close(serv_sock);

      write(clnt_sock, intro, sizeof(intro));
      read(clnt_sock, buffer, BUFSIZE);   /* 클라이언트의 선택 수신 */
      write(fd1[1], buffer, 1);     /* 부모 프로세스로 선택 전송 */
      str_len = read(fd2[0], buffer, BUFSIZE);  /* 부모 프로세스로부터 결과 수신 */
      write(clnt_sock, buffer, str_len);  /* 클라이언트로 결과 전송 */
     
      puts("연결 종료");
      close(clnt_sock);
      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+1)%3==b%3)
    return 1;
  else
    return -1;
}

void error_handling(char *message)
{
  fputs(message, stderr);
  fputc('\n', stderr);
  exit(1);
}





/* ipcgame_clnt.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#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 <IP> <port>\n", argv[0]);
    exit(1);
  }

  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=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!");

  /* 가위 바위 보 게임 시작 */
  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[str_len]=0;
  puts(message);
 
  close(sock);
  return 0;
}

void error_handling(char *message)
{
  fputs(message, stderr);
  fputc('\n', stderr);
  exit(1);
}

/* pipe2.c */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#define BUFSIZE 30

int main(int argc, char **argv)
{
  int fd[2];
  char buffer[BUFSIZE];
  pid_t pid;
  int state;

  state = pipe(fd);
  if(state == -1){
    puts("pipe() error");
    exit(1);
  }

  pid = fork();
  if(pid == -1){
    puts("fork() error");
    exit(1);
  }
  else if(pid==0){  /*자식 프로세스의 경우 */
    write(fd[1], "Good!", 6);
    sleep(2);
    read(fd[0], buffer, BUFSIZE);
    printf("자식 프로세스 출력 : %s \n\n",  buffer);
  
  }
  else{             /* 부모 프로세스의 경우 */
    read(fd[0], buffer, BUFSIZE);
    printf("부모 프로세스 출력 : %s \n", buffer);
    write(fd[1], "Really Good", 12);
    sleep(3);  /* 큰의미 없음 : 출력 좋게 하려고 */
  }

  return 0;
}





/* pipe3.c */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#define BUFSIZE 30

int main(int argc, char **argv)
{
  int fd1[2], fd2[2];
  char buffer[BUFSIZE];
  pid_t pid;

  if(pipe(fd1)==-1 || pipe(fd2)==-1) {
    puts("pipe() error");
    exit(1);
  }

  pid = fork();

  if(pid ==-1){
    puts("fork() error");
    exit(1);
  }
  else if(pid==0){
    write(fd1[1], "Good!", 6);
    read(fd2[0], buffer, BUFSIZE);
    printf("자식 프로세스 출력 : %s \n\n",  buffer);
  }
  else{
    read(fd1[0], buffer, BUFSIZE);
    printf("부모 프로세스 출력 : %s \n", buffer);
    write(fd2[1], "Really Good", 12);
    sleep(1);
  }

  return 0;
}

/* pipe1.c */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#define BUFSIZE 30

int main(int argc, char **argv)
{
  int fd[2]; // 파이프 리턴값 저장할 배열 선언.
  char buffer[BUFSIZE];
  pid_t pid;
  int state;

  state = pipe(fd); // 파이프 생성
  if(state == -1) {
    puts("pipe() error");
    exit(1);
  }

  pid = fork(); // 프로세스 복사

  if(pid == -1){ // 프로세스 복사가 안된다면
    puts("fork() error");
    exit(1);
  }
  else if(pid==0){ // 자식프로세스 라면
    write(fd[1], "Good\n", 6);
  }
  else{ // 부모 프로세스 라면
    read(fd[0], buffer, BUFSIZE);
    puts(buffer);
  }

  return 0;
}

/* echo_multiserv.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>

#define BUFSIZE 30

void error_handling(char *message);
void z_handler(int sig);

int main(int argc, char **argv)
{
  int serv_sock;
  int clnt_sock;
  struct sockaddr_in serv_addr;
  struct sockaddr_in clnt_addr;

  struct sigaction act;
  int addr_size, str_len, state;
  pid_t pid;
  char message[BUFSIZE];

  if(argc!=2){
    printf("Usage : %s <port>\n", argv[0]);
    exit(1);
  }

  act.sa_handler=z_handler;
  sigemptyset(&act.sa_mask);
  act.sa_flags=0;
 
  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(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");

  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 ) {      /* 부모 프로세스인 경우 */
      puts("연결 생성");
      close(clnt_sock);
      continue;
    }
    else {                  /* 자식 프로세스의 경우 */
      close(serv_sock);

      /* 자식 프로세스의 처리영역 : 데이터 수신 및 전송 */
      while( (str_len=read(clnt_sock, message, BUFSIZE)) != 0) {
  write(clnt_sock, message, str_len);
  write(1, message, str_len);
      }
      puts("연결 종료");
      close(clnt_sock);
      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));
 
}

void error_handling(char *message)
{
  fputs(message, stderr);
  fputc('\n', stderr);
  exit(1);
}





/* echo_multiclnt.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#define BUFSIZE 30

void error_handling(char *message);

int main(int argc, char **argv)
{
  int sock;
  pid_t pid;
  char message[BUFSIZE];
  int str_len, recv_len, recv_num;
  struct sockaddr_in serv_addr;

  if(argc!=3){
    printf("Usage : %s <IP> <port>\n", argv[0]);
    exit(1);
  }

  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=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!");

  pid=fork();
  if(pid==0){
    while(1){
      fputs("전송할 메세지를 입력 하세요 (q to quit) : ", stdout);
      fgets(message, BUFSIZE, stdin);
      if(!strcmp(message,"q\n")) {
    shutdown(sock, SHUT_WR);
    close(sock);
    exit(0);
      }
      write(sock, message, strlen(message));
    } /* while(1) end */
  } /* if(pid==0) end */
  else {
    while(1){
      int str_len = read(sock, message, BUFSIZE);
      if(str_len == 0){
    exit(0);
   }
      message[str_len]=0;
      printf("서버로부터 전송된 메시지 : %s\n", message);
    } /* while(1) end */
  } /* else end*/
 
  close(sock);
  return 0;
}

void error_handling(char *message)
{
  fputs(message, stderr);
  fputc('\n', stderr);
  exit(1);
}

/* sigint.c */

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void handler(int sig);

int main(int argc, char **argv)
{
  int state;
  int num=0;

  signal(SIGINT, handler);
  while(1)
  {
    printf("%d : 대기중 \n", num++);
    sleep(2);
    if(num>5)
      break;
  }
  return 0;
}

/*시그널 처리 함수 */
void handler(int sig)
{
  signal(SIGINT, handler);
  printf("전달된 시그널은 %d \n", sig);
}





/* sigint2.c */

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void handler(int sig);

int main(void)
{
  int state;
  int num=0;
 
  struct sigaction act;      /* 핸들러 구조체 변수 */
  act.sa_handler=handler;    /* 핸들러 함수 지정   */
  sigemptyset(&act.sa_mask); /* sm_mask의 모든 비트를 0으로 설정 */
  act.sa_flags=0;           

  state=sigaction(SIGINT, &act, 0); /* 시그널 핸들러 등록 */
  if(state != 0){
    puts("sigaction() error ");
    exit(1);
  }

  while(1){
    printf("%d : 대기중 \n", num++);
    sleep(2);
    if(num>5) break;
  }
  return 0;
}

/* 시그널 처리 함수 */
void handler(int sig)
{
  printf("전달된 시그널은 %d \n", sig);
}





/* sigalrm.c */

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>

void timer(int sig);

int main(int argc, char **argv)
{
  int state;

  struct sigaction act;
  act.sa_handler=timer;
  sigemptyset(&act.sa_mask);
  act.sa_flags=0;
 
  state=sigaction(SIGALRM, &act, 0); /* 시그널 핸들러 등록 */
  if(state != 0){
    puts("sigaction() error ");
    exit(1);
  }
 
  alarm(5); /* 5초 후에 SIGALRM 시그널 예약 */
  while(1){
    puts("대기중");
    sleep(2);
  }
  return 0;
}

void timer(int sig)
{
  puts("예약 하신 시간이 되었습니다!! \n");
  exit(0);
}





/* zombie_handler.c */

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

void z_handler(int sig);

int main(int argc, char **argv)
{
  pid_t pid;
  int state, i;

  struct sigaction act;
  act.sa_handler=z_handler;
  sigemptyset(&act.sa_mask);
  act.sa_flags=0;
 
  state=sigaction(SIGCHLD, &act, 0); /* 시그널 핸들러 등록 */
  if(state != 0){
    puts("sigaction() error ");
    exit(1);
  }
 
  pid=fork();
  if(pid==0) {
    printf("자식 프로세스 생성 : %d \n", getpid());
    exit(3);
  }
  else {
    sleep(3);
  }

  return 0; 
}

void z_handler(int sig)
{
  pid_t pid;
  int rtn;

  while( (pid=waitpid(-1, &rtn, WNOHANG)) > 0){
    printf("소멸된 좀비의 프로세스 ID : %d \n", pid);
    printf("리턴된 데이터 : %d \n\n", WEXITSTATUS(rtn));
  }
}

+ Recent posts