멀티 프로세스
멀티플렉싱 : 프로세스 하나가 여러 클라에게 데이터 전송
select()
파일 디스크립터를 모을 땐 관찰항목(수신, 전송, 예외)에 따라서 구분해서 모아야 한다.
이를 위해 fd_set형 변수를 사용한다.
fd_set 값 편집 매크로 함수
FD_ZERO() : 모든 비트 0 초기화FD_SET() : 파일 디스크립터 정보 등록FD_CLR() : 파일 디스크립터 정보 삭제FD_ISSET() : 파일 디스크립터 정보 있으면 양수 반환관찰 범위 : 가장 큰 파일 디스크립터 값에 1 더함
타임아웃 설정
int main(int argc, char *argv[])
{
fd_set reads, temps;
int result, str_len;
char buf[BUF_SIZE];
struct timeval timeout;
FD_ZERO(&reads);
FD_SET(0, &reads); // 0 is standard input(console)
/*
timeout.tv_sec=5;
timeout.tv_usec=5000;
*/
while(1)
{
temps=reads;
timeout.tv_sec=5;
timeout.tv_usec=0;
result=select(1, &temps, 0, 0, &timeout);
if(result==-1)
{
puts("select() error!");
break;
}
else if(result==0)
{
puts("Time-out!");
}
else
{
if(FD_ISSET(0, &temps))
{
str_len=read(0, buf, BUF_SIZE);
buf[str_len]=0;
printf("message from console: %s", buf);
}
}
}
return 0;
}

int main(int argc, char *argv[])
{
int serv_sock, clnt_sock;
struct sockaddr_in serv_adr, clnt_adr;
struct timeval timeout;
fd_set reads, cpy_reads;
socklen_t adr_sz;
int fd_max, str_len, fd_num, i;
char buf[BUF_SIZE];
if(argc!=2) {
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
serv_sock=socket(PF_INET, SOCK_STREAM, 0);
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_adr.sin_port=htons(atoi(argv[1]));
if(bind(serv_sock,(struct sockaddr*) &serv_adr, sizeof(serv_adr))==-1)
error_handling("bind() error");
if(listen(serv_sock, 5)==-1)
error_handling("listen() error");
FD_ZERO(&reads);
FD_SET(serv_sock, &reads);
fd_max=serv_sock;
while(1)
{
cpy_reads=reads;
timeout.tv_sec=5;
timeout.tv_usec=5000;
if((fd_num=select(fd_max+1,&cpy_reads,0,0,&timeout))==-1)
break;
if(fd_num==0)
continue;
for(i=0; i<fd_max+1; i++)
{
if(FD_ISSET(i, &cpy_reads))
{
if(i==serv_sock) // connection request!
{
adr_sz=sizeof(clnt_adr);
clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_adr, &adr_sz);
FD_SET(clnt_sock, &reads);
if(fd_max<clnt_sock)
fd_max=clnt_sock;
printf("connected client: %d \n", clnt_sock);
}
else // read message
{
str_len=read(i, buf, BUF_SIZE);
if(str_len==0) // close request;
{
FD_CLR(i, &reads);
close(i);
printf("closed client: %d \n", i);
}
else
{
write(i, buf, str_len); // echo!
}
}
}
}
}
close(serv_sock);
return 0;
}

FD_ISSET으로 확인하려는 파일 디스크립터가 맞는지 확인한다윈도우의 fd_set은 비트 배열이 아니라
소켓 핸들 수 기록할 fd_count와 소켓 핸들 저장할 fd_array로 이루어졌다.
윈도우 소켓 핸들은 0부터 시작하지도 않고, 정수 값 사이에도 관계성 없기 때문이다.