본문 바로가기
코스웨어/15년 스마트컨트롤러

20150825 -21번-여지윤-일일업무일지- 채팅프로그램

by 알 수 없는 사용자 2015. 8. 25.
728x90
반응형

5~8교시

☆S/W★


● NetWork


□ select 함수를 이용한 채팅프로그램 (2회차)


- server 내에서 인원수가 한명이 아닌 여러명을 추가 시켜주기 위한 변수를 추가 시켜준다.


- 변수 iMsock 을 변수로 선언한다. (위에 그림에서 iMsock 을 isock +1 이라고 하였으나 select 함수에서 +1을 시켜주었기 때문에 iMsock = isock +1은 불필요하다)


- for문으로 인원수를 체크하고 다중의 인원수가 넘치지 않게끔 if문을 사용하여 최대값보다 넘치는 것을 방지한다.


- server 가 동작을 하는 조건은 3가지 정도이며 , 신규유저를 받을때, 그리고 대화(나가는 유저 포함), 서버에서 입력받을때가 있다.


- 전부 if문으로 처리하며 다음과 같은 그림으로 확인 할 수가 있다.



- if문을 for문으로 감쌀때 일반적으로 한명이 접속하여 대화를 하는 것이 아니라 여러명의 객체 인원을 수용하고 사용하며, 대화하는 것이기 때문에 if문 만으로는 여러명의 접속과 대화가 불가능하다.


- 그렇기 때문에 for문으로 감싸서 모든 사용자가 대화를 할 수 있게끔 해주어야 하므로 인원수만큼 돌려주어야 한다.


- 하지만 여기서 문제점은 이렇게 해버린다면 나중에 종료할때 한번에 종료가 된다.


- 위의 내용을 조금 더 수정하자면 다음과 같이 수정할 수 있다.



- 아까도 설명했듯이 이 코드를 사용하고 종료를 하게 되면 인원이 몇명이든 서버가 끊기면서 모든 인원의 접속이 종료가 되기 때문에, client.c를 확인하여 수정 해야만 한다.


□ 실행 결과



- 다음과 같은 실행 결과를 얻을 수가 있다.


□ server.c


#include "smartsock.h"

 int main()
 {
     int isock;
      int iRet;
      unsigned int uiUsr;
      unsigned int uiCnt;
      unsigned int uiCnt2;
      int iCsock[MAX_USER];
      fd_set fdRead;
      char cBuf[BUF_SIZE];
      int iMsock;
      socklen_t uiSocklen = sizeof(struct sockaddr);
      struct sockaddr_in staddr;
 
      if((isock = socket(AF_INET, SOCK_STREAM, 0))<0)
      {
          perror("socket error : ");
          return 10;
      }
 
      bzero(&staddr, sizeof(staddr));
      staddr.sin_family = AF_INET;
      staddr.sin_addr.s_addr = inet_addr("192.168.0.171");
      staddr.sin_port = htons(PORT);
 
      iRet = bind(isock, (struct sockaddr *)&staddr, sizeof(staddr));
      if(iRet < 0)
      {
          perror("bind error ");
          close(isock);
          return 20;
 
     }

      iRet = listen(isock , 5);
      if(iRet < 0)
      {
          perror("listen error ");
          close(isock);
          return 30;
      }
 
      uiUsr = 0;
 
      while(1)
      {
          FD_ZERO(&fdRead);
          FD_SET(0&fdRead);
          FD_SET(isock, &fdRead);
 
          iMsock = isock;
 
          for(uiCnt = 0; uiCnt < uiUsr; ++uiCnt)
          {
              FD_SET(iCsock[uiCnt], &fdRead);
 
              if(iMsock < iCsock[uiCnt])
              {
                  iMsock = iCsock[uiCnt];
              }
          }
 
          select(iMsock + 1&fdRead, 000);
 
          if(0 != FD_ISSET(isock, &fdRead))
          {
              iCsock[uiUsr] = accept(isock, (struct sockaddr *)&staddr, &uiSoc
 
              if(iCsock[uiUsr] < 0)
              {
                  perror("Accept error ");
                  continue;
              }
              printf("incomming client!!!\n");
              printf("%s\n", inet_ntoa(staddr.sin_addr));
              write(iCsock[uiUsr], "Welcome!!", sizeof("Welcome!!"));
              ++uiUsr;
          }
 
          if(0 != FD_ISSET(0&fdRead))
          {
              iRet = read(0, cBuf, MSG_SIZE);
              cBuf[iRet - 1= 0;
              for(uiCnt = 0; uiCnt < uiUsr; ++uiCnt)
              {
                  write(iCsock[uiCnt], cBuf, MSG_SIZE);
              }
          }
 
          for(uiCnt = 0; uiCnt < uiUsr; ++uiCnt)
          {
              if(0 != FD_ISSET(iCsock[uiCnt], &fdRead))
              {
                  read(iCsock[uiCnt], cBuf, MSG_SIZE);
 
                  for(uiCnt2 = 0; uiCnt2 < uiUsr; ++uiCnt2)
                  {
                     if(uiCnt != uiCnt2)
                     {
                         write(iCsock[uiCnt2],cBuf, MSG_SIZE);
                     }
                 }
                 if(0 == strncmp(cBuf, MSG_END, strlen(MSG_END)))
                 {
                     close(iCsock[uiCnt]);
                     --uiUsr;
                     iCsock[uiCnt] = iCsock[uiUsr];
                 }
             }
         }
     }

     close(isock);
     for(uiCnt = 0; uiCnt < uiUsr; ++uiCnt)
     {
         close(iCsock[uiCnt]);
     }

     return 0;



728x90