멀티 플렉싱

이동욱

2021/08/21

Categories: 네트워크

멀티 플렉싱


SELECT () 함수


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

인자

매크로 설명
FD_ZERO(fd_set *fdset) fdset 변수의 모든 비트를 0으로 설정
FD_SET(int fd, fd_set *fdset) fdset 변수 중 fd에 해당하는 비트를 1로 설정
FD_CLR(int fd, fd_set *fdset) fdset 변수 중 fd에 해당하는 비트를 0으로 설정
FD_ISSET(int fd, fd_set *fdset) fdset 변수 중 fd에 해당하는 비트가 1이면 양수를 반환한다.
struct timeval {
  long tv_sec; // 초
  long tv_usec; // 마이크로 초
}

SELECT() 함수의 활용


  1. socket 호출 (듣기 소켓 생성)
  2. bind 호출
  3. listen 호출

관찰 대상이 되는 디스크립터 셋 형성

  • 루프 시작
  • 듣기 소켓을 관찰하여 읽을 데이터가 있을 경우 accept를 호출한다.
  • accept 호출로 전송 소켓 디스킙터를 관찰 대상에 등록한다.
  • 전송 소켓을 관찰하여 읽을 데이터가 있을 경우 입출력을 한다.
  • 루프 끝

예제

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>

void error_proc(const char*);

int main(int argc, char *argv[]) {
  int listen_sd, connect_sd;
  struct sockaddr_in server_addr, client_addr;
  int client_addr_len, read_len, str_len;
  char read_buffer[BUFSIZ];
  int max_fd = 0;
  fd_set default_fds, read_fds;
  int res, i;

  if (argc != 2) {
    printf("usage: %s [port number]\n", argv[0]);
    return -1;
  }

  printf("server start...\n");
  listen_sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (listen_sd == -1) error_proc("socket");
  memset(&server_addr, 0, sizeof(server_addr));

                                                                                        31,0-1        10%
        } else { // 듣기 소켓 외의 다른 소켓이 읽기 준비 상태가 되면 IO를 수정
          read_len = read(i, read_buffer, sizeof(read_buffer) -1);
          if (read_len == 0) {
            fprintf(stderr, "a client is disconnected... \n");
            FD_CLR(i, &default_fds);
            close(i);
            continue;
          }
          read_buffer[read_len] = '\0';
          printf("client (%d): %s\n", i - 3, read_buffer);
          write(i, read_buffer, strlen(read_buffer));
        }
      }
    }
  }
  close(listen_sd);
  return 0;
}

void error_proc(const char *str) {
  fprintf(stderr, "error: %s\n", str);
  exit(1);
}

참고 문헌


>> Home