Busan IT/공장내 Network2015. 7. 28. 17:34

==================================Outline====================================

채팅 멀티프로세스

----------------------------------------------------------------------------

채팅 멀티프로세스 

리눅스에서는 프로그램의 리턴 값이 저장되고 echo $? 명령어를 사용하여 그 return 값을 출력할 수 있다.

//아무 일도 수행하지 않는 프로세스를 좀비 프로세스라고 한다.

 

fork함수를 사용하여 서버와 클라이언트의 멀티 프로세스 작업을 해보자.

 

우선 fork를 사용하기 위해여 헤더파일이 <unistd.h>를 추가해준다.

 

다음 fork함수의 리턴 값을 받기 위해 타입이 정의된 pid_t 변수를 하나 선언해 준다.

 

fork함수의 리턴 값이 0보다 크면 부모 프로세스이고 이 값은 프로세스 ID를 반환한다.

반면에 자식 프로세스는 0을 반환한다.

 

 

 

우선 fork함수를 통하여 클라이언트에서 쓰기/읽기를 분리하자.

writeread함수 무한 while문 전에 fork 함수를 사용하여 프로세스를 복사한다.

부모 프로세스에는 읽기/자식 프로세스는 쓰기만 하도록 if문을 사용하여 분리해준다.

 

 

서버에서는 랑데부 소켓(클라이언트 연결 전용)과 커뮤니케이션 소켓(통신전용)을 사용한다.

if문을 사용하여 분리한다.

 

/*** 소스 ***/


<server.c>

#include "smartsock.h"
#include <unistd.h>

int main(void)
{
  int iSock;   //소켓 함수의 반환 값을 받는 변수
  int icSock;   //accept의 반환 값을 받는 변수
  int iRet;
  struct sockaddr_in stAddr;
  socklen_t uiSockLen=sizeof(struct sockaddr);
  char cBuff[BUF_SIZE];
  const char * cP;
  pid_t pid;

  iSock = socket(AF_INET, SOCK_STREAM, 0);    //AF_INET = 2, 
  if(0 > iSock)
  {
    perror("socket : ");
    return -1;
  }
  // stAddr구조체에 socket연결을 위한 필수 정보 입력  setting
  bzero(&stAddr, sizeof(stAddr));            //구조체 비우기(0으로 채우기)
  stAddr.sin_family = AF_INET;               //#define AF_INET 2 /* IP protocol family. */
  stAddr.sin_addr.s_addr = inet_addr(IP);    //IP와 PORT값은 헤더파일에 정의되어 있다.
  stAddr.sin_port = htons((PORT));

  iRet = bind(iSock, (struct sockaddr *)&stAddr,sizeof(stAddr));
  if(iRet < 0)
  {
    perror("bind : ");
    close(iSock);

    return -2;
  }
  iRet = listen(iSock, 5);
  if(iRet != 0)
  {
    perror("listen : ");
    close(iSock);

    return -3;
  }
  while(1
  {
    icSock = accept(iSock, (struct sockaddr *)&stAddr, &uiSockLen); //접속자의 정보가 stAddr에 입력된다.

    if(icSock < 0)
    {
      perror("Accept : ");
      close(iSock);

      return -4;
    }
/////////////////////////////멀티 프로세스///////////////////////////////////////////
    pid = fork();

    if(pid ==  0)  //자식 프로세스이면 while문 break
    {
      break;
    }
  }
  close(iSock);

  printf("Incoming Client \n");
  //cP = inet_ntoa(stAddr.sin_addr);
  printf("Client IP :%s\n", inet_ntoa(stAddr.sin_addr));
  printf("Client Port : %d\n", ntohs(stAddr.sin_port));  

  write(icSock, "Welcome :)"sizeof("Welcome :)"));

  while(1)
  {
    read(icSock, cBuff, MSG_SIZE);
    printf("[client]: [%s]\n", cBuff);

    write(icSock, cBuff, MSG_SIZE);
    if(0 == strncmp(MSG_END, cBuff, strlen(MSG_END) ) )
      break;

  }
  close(icSock);
  return 0;
}

<client.c>

#include "smartsock.h"
#include <unistd.h>

int main(void)
{
  struct sockaddr_in stAddr;
  int iSock;
  int iRet;
  char cBuff[BUF_SIZE];
  socklen_t uiSockLen=sizeof(struct sockaddr);
  pid_t pid;

  iSock = socket(AF_INET, SOCK_STREAM, 0);
  if(0 > iSock)
  {
    perror("socket : ");
    return -1;
  }

  bzero(&stAddr, sizeof(stAddr));
  stAddr.sin_family = AF_INET;

  stAddr.sin_addr.s_addr = inet_addr("192.168.0.173");
  stAddr.sin_port = htons((PORT));

  iRet = connect(iSock, (struct sockaddr *)&stAddr, uiSockLen);
  if(0 > iRet)
  {
    perror("connect : ");
    return -2;
  }

  pid = fork();

  if(pid > 0)
  {
    close(0);
    while(1)
    {
      read(iSock, cBuff, MSG_SIZE);
      printf("[server]: [%s]\n", cBuff);

      if(0 == strncmp(MSG_END, cBuff, strlen(MSG_END)))
        break;
    }

  }
  else
  {
    close(1);
    while(1)
    {
      iRet = read(0, cBuff, MSG_SIZE);
      cBuff[iRet-1= 0;
      write(iSock, cBuff, MSG_SIZE);

    }

  }

  close(iSock);
  return 0;
}

 

여러 개의 클라이언트가 접속했음을 알 수 있다.





멀티 프로세서 분리된 서버/클라이언트의 통신은 가능하지만 서버 간의 통신이 없기 때문에 분리된 클라이언트들은 다른 클라이언트가 서버로 보낸 메시지를 볼 수 없다. 때문에 PIC(Internal Process Communication)이 필요하다.

 

To be continued...

 

반응형

'Busan IT > 공장내 Network' 카테고리의 다른 글

Hacker School level 1, VMware 해커스쿨 서버 설치  (0) 2015.08.13
IPC(3)  (0) 2015.08.10
Three-way Handshake, fork 함수, execl 함수  (0) 2015.07.24
TCP analyzer  (0) 2015.07.22
TCP analyzer(진행 중)  (0) 2015.07.17
Posted by newind2000