이 글은 윤성우의 TCP/IP 소켓 프로그래밍 책을 참고하였습니다.

순서

I. 리눅스와 윈도우의 차이

II. Window 서버 구현


window - Linux가 거의 비슷하므로 기본 개념은 아래 글에서 참조하면 된다.

2020/12/18 - [Programming/Network] - [Network][TCP/IP] 멀티플렉싱(2)_select 함수로 구현 (Linux)

 

I. 리눅스와 윈도우의 차이

 

1. timeval 구조체

타임아웃을 지정하기 위한 timeval 구조체에 차이가 있다.

큰 차이는 없지만 기본적으로 Linux는 timeval을 사용하면 되지만
Window에서는 다음과 같이 정의가 되어있다.

typedef struct timeval
{
    long tv_sec;  // 초
    long tv_usec; // 마이크로초
} TIMEVAL;

위 코드처럼 typedef선언으로 TIMEVAL을 사용하도록 되어있다. 이게 차이 끝이다.


2. fd_set 구조체

fd_set 자료형은 가장 중요한, 비트의 배열로 구성되어있는 fd의 집합이었다.

하지만 Window에서는 아니다.

우선 기본적으로 "파일 디스크립터"라는 개념은 리눅스에서만 사용했었고
윈도우에서는 다른 이름이 있었다.

바로 SOCKET이라는 자료형으로 "소켓 핸들"이라고 불렀었다.

따라서 fd_set이라는 자료형의 이름은 동일하지만 구조는 다음과 같은 구조체이다.

typedef struct fd_set
{
    u_int  fd_count;
    SOCKET fd_array[FD_SETSIZE];
} fd_set;

fd_max가 아닌 소켓의 핸들 수(fd_count)가 있고 SOCKET배열이 있다.

왜 이렇게 했을까를 먼저 생각해보면,

fd는 생성시마다 0부터 ++되서 하나씩 증가하지만,
소켓 핸들은 아무 관계도없고 어떤수가 나올지 모른다!

따라서
fd_count에 fd_set에 저장되어 있는 핸들 수를 기록하고,
fd_array에 소켓핸들을 저장한다.

하지만 걱정하지말자.

fd_set의 이름이 그대로인 이유는 바로 fd_set을 조작하기 위한
4가지 매크로 함수들의 사용법은 동일하다는 것이다!!

구현상에서만 아주 조금 차이가 있는데,

1. for문으로 fd_max까지 쭉 도는 부분을 fd_max 대신 fd_set. fd_count로 바꾸면 되고
2. i 번째 자체가 fd였다면 이번에는 fd_set. fd_array[i]가 될 뿐이다.

 


II. Window 서버 구현

이것도 차이점만 보자면...

// Linux 정의 struct timeval timeout

// 윈도우는 아래와 같이 정의
TIMEVAL timeout;


fdNum = select(0, &cpyReads, 0, 0, &timeout) // 으로 호출하고 나서

//리눅스는 다음과 같이 구현했었음.
for(i=0; i<fd_max+1;i++)
{
    if(FD_ISSET(i, &cpyReads))
    {
        if(i==serv_sock)
        ~~~~
    }
}

//윈도우는 다음과 같이 구현함
for(i = 0; i<reads. fd_count; i++)
{
    if(FD_ISSET(reads.fd_array[i], &cpyReads))
    {
        if(reads.fd_array[i] == hServSock)
        ~~~~
    }
}

+ Recent posts