파이프에서 자식프로세스가 보낸것을 부모프로세스가 받는과정중 질문입니다

ch0nn0m의 이미지

윤성우 저자의 tcp/ip를 보고 있는데요..
진하게 주석처리로 해놓은 부분이 잘 이해가 가지 않습니다

자식프로세스가 클라이언트의 결과를 받아서 부모프로세스로 보낸뒤
부모프로세스가 그것을 받는부분인데요...
read(fd1[0], &buffer[1], BUFSIZE-1);  
여기..char buffer[BUFSIZE]; 로 선언이 되어있는데...여기에서 buffer[1]이 가능한건지요??
이해가 잘안가네요...

#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) : "; 
  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) { 
      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);      
<span>//이부분이 이해가 잘 가지 않습니다...&buffer[1],BUFSIZE-1...왜 이렇게 받는지..?
//char buffer[BUFSIZE]; 로 선언이 되어있는데...여기에서 buffer[1]은 무엇을 의미하는건지..?</span>
      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);
}
antaran의 이미지

주석으로 질문하신 부분만 보고 답변 드립니다. 혹시 잘못 된 부분이 있더라도 양해를...

// stdout으로 "가위 바위 보" 어쩌구 하는 intro 내용을 출력
write(1, intro, sizeof(intro));

// stdin에서 buffer에 BUFSIZE만큼 읽어들임.
read(0, buffer, BUFSIZE);

// pipe라고 하셨으니 pipe에서 buffer[1] 부터 buffer[BUFSIZE - 1]까지 (BUFSIZE - 1) byte 만큼 읽음.
// 즉, 위 stdin에서의 입력중 첫글자만 남기고 나머지는 pipe에서의 입력으로 overwrite한다고 보시면 될 듯.
read(fd1[0], &buffer[1], BUFSIZE-1);
//이부분이 이해가 잘 가지 않습니다...&buffer[1],BUFSIZE-1...왜 이렇게 받는지..?
//char buffer[BUFSIZE]; 로 선언이 되어있는데...여기에서 buffer[1]은 무엇을 의미하는건지..?

그나저나 잘 돌아가나요? stdin에서 BUFSIZE만큼 안들어 오면 block되는 거 아닌가 싶은데요.

뭐 어찌됬건 큰 의미가 있는 코드가 아니니 고민 하실필요까지는 없을 듯 합니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.