Busan IT/공장내 Network2015. 8. 18. 16:54

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

select 함수

select함수를 사용한 채팅프로그램 작성

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

select 함수 



 

 

#include <sys/time.h>

#include <sys/types.h>

#include <unistd.h>

#include <stdio.h>

 

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

 

fd_set 구조체가 인자로 사용된다. fd_set 구조체의 크기는128byte, 1024bit이다. byte단위가 아닌 flag형식인 bit 단위로 1024bit를 1(set)과 0으로 조작한 후 select함수에 넣어 사용하게 될 것이다.

 

인자들(Arguments)

 

nfds

[입력] 버클리 소켓과 호환되는 소켓을 제외 하고는 이 매개변수는 무시됩니다. 버클리 소켓에서 이 매개변수는 I/O 변화를 감지 할 총 소켓의 갯수+1 의 값을 지정하는 용도로 사용합니다.

 

readfds

[/출력] 읽기상태의 변화를 감지할 소켓을 지정합니다.

 

writefds

[/출력] 쓰기상태의 변화를 감지할 소켓을 지정합니다.

 

exceptfds

[/출력] 예외상태 변화를 감지할 소켓을 지정합니다.

 

timeout

[입력] select 함수가 기다리기 위한 시간입니다. NULL 일경우 지정한 I/O변화가 발생했을 때까지 계속 기다립니다.


fd_set구조체 조작 함수들


FD_ZERO: fd_set 구조체에서 모든 비트를 0으로 채우는 함수

FE_SET: fd_set 구조체에서 선택 비트를 1로 채우는 함수

FD_CLR: fd_set 구조체에서 선택 비트를 0으로 채우는 함수 

FD_ISSET: fd_set 구조체해서 해당 비트의 상태를 반환하는 함수


select 함수

select함수의 Read, Write, Error 중에서 값이 set으로 된 것들만 감시하게 된다.

 

select는 블록킹 함수로써(scanf같은) 감시하던 파일들에서 이벤트가 발생 했을 때 블록 상태가 풀리게 된다.

 

select의 마지막 인자는 블록킹 대기 상태의 시간을 나타내며 ‘0’을 입력 시 무한대기 상태가 된다.

 

select 함수는 등록된 파일 중 데이터 변화가 생긴 개수를 반환하고 함수 실패 시 -1을 반환한다.

 

첫 번째 인자에서 감시하는 수에서 가장 큰 수에 +1 한 값을 넣어주면 된다.

 

select함수를 사용한 채팅프로그램 작성

 

select함수를 사용하면 멀티 프로세스 없이 채팅 프로그램을 작성할 수 있다.

 

전에 작성하던 헤더파일만 사용하고 serverclient채팅 프로그램을 다시 작성해보자.

 

우선 클라이언트부터 만든다.

 

클라이언트 채팅 프로그램을 만들기 위한 흐름은 아래와 같다.

 

socket() -> connect() -> read() & write() -> close()


/*** 소스 ***/

#include "smartsock.h"

int main(void)
{
  int iFd;
  struct sockaddr_in stAddr;
  int iLen;
  int iRtn;
  char cBuf[BUF_SIZE];
  fd_set fdRead;

  /*** socket ***/
  iFd = socket(AF_INET, SOCK_STREM, 0);
  if(-1 == iFd)
  {
    perror("socket:");
    return 100;
  }

  /*** structure setting ***/
  stAddr.sin_family = AF_INET;
  stAddr.sin_addr.s_addr = inet_addr(IP);
  stAddr.sin_port = htons(PORT);

  iLen = sizeof(struct sockaddr_in);

  /*** connect ***/
  iRtn = connect(iFd, (struct sockaddr *)&stAddr, iLen);
  if(-1 == iRtn)
  {
    perror("connect:");
    close(iFd);
    return 200;
  }

  while(1)
  {
    FD_ZERO(&fdRead);  
    FD_SET(0&fdRead);
    FD_SET(iFd, &fdRead);  //    
  }
  

  /*** read & write ***/
  memset(cBuf, 0, BUF_SIZE);
  iRtn = read(0, cBuf, BUF_SIZE);
  

  close(iFd);
  return 0;
}

 

반응형
Posted by newind2000