2011-10-03 3 views
19

내 소켓 간의 통신을 위해 선택 기능을 사용하고 있습니다. while 루프를 사용하고 있습니다. -루프 내부의 select()에 대한 FD_SET/FD_ZERO가 필요한 이유는 무엇입니까?

while(!done) { 

    FD_ZERO(&read_flags); 
    FD_ZERO(&write_flags); 
    FD_SET(comm_fd1, &read_flags); 
    FD_SET(comm_fd2, &read_flags); 
    FD_SET(STDIN_FILENO, &read_flags); 
    FD_SET(comm_fd1, &write_flags); 
    FD_SET(comm_fd2, &write_flags); 
    FD_SET(STDIN_FILENO, &write_flags); 

    //call select 
    sel = select(comm_fd1+comm_fd2+1, &read_flags, &write_flags, (fd_set*)0, &waitd); 

및 클라이언트 측에서 다른 변수와 동일합니다. 나는 튜토리얼 온라인에서이 기본 기술을 얻었고 그냥 따라 갔다. 그런 다음 그것은 나를 때렸습니다 - 왜 내가 루프를 할 때마다 파일 디스크립터를 추가하고 파일 디스크립터를 추가합니까? 그들은 이미 추가 된 경우, 왜 그들을 취소하고 다시 추가? 그래서 나는 한동안이 일을 한 번만 해봤고 코드는 더 이상 똑같이 작동하지 않습니다. 왜 누군가가 설명 할 수 있습니까? select가 세트의 내용을 수정했기 때문입니까? 도움이나 통찰력이 있으면 감사하겠습니다.

답변

21

select이 반환되면 세트를 업데이트하여 읽기/쓰기/예외가 준비된 파일 설명자를 표시합니다. 다른 모든 플래그는 지워졌습니다.

다른 선택을 시작하기 전에 지워진 파일 설명자를 다시 활성화해야합니다. 그렇지 않으면 더 이상 해당 파일 설명자를 기다리지 않습니다.

파일 디스크립터 세트를 변경해야하는 경우 (예 : 새로 열린 소켓을 읽기 세트에 추가하는 경우), 다시 들어가는 것이 좋은 습관이 될 수 있습니다. 그것을 지우고 매번 다시 작성하여 프로그램의 상태가 변경 될 때까지 수정하십시오.

+2

또한 루프 할 때마다 timeval 구조체 (예 : waitd)를 재설정해야한다는 점에 유의하십시오. –

3

select가 세트의 내용을 수정했기 때문입니까?

예, select이 반환 된 후에는 준비된 디스크립터 만 세트 내에 남아 있습니다.

관련 문제