2010-04-08 5 views
2

0 개 이상의 소켓을 가질 수있는 fd 세트가 있다고 가정하십시오. 비어있는 fd 세트에서 select 연산을 호출하려고하면 -1이 fds의 수로 설정되어 오류를 의미합니다. 그래서이 문제를 극복하기 위해 무엇을 제안하겠습니까? 빈 경우 호출하지 말고 루프가 있으며 fd 세트는 0 개 이상의 소켓을 가질 수 있습니다. 이 문제에 대한 최선의 접근 방법은 무엇입니까? (우리는 C 프로그래밍 언어를 사용합니다)소켓 빈 fd 세트로 선택

+0

'nfds' 인수를 0으로 설정하여'select'를 호출합니까? 어떤 플랫폼을 사용하고 있습니까? – Hasturkun

+0

우리의 삶을 좀 더 쉽게 만들기 위해 코드를 게시하고 싶을 수도 있습니다. Raymond Chen은 총기 심령 디버거 일지 ​​모르지만 우리 중 일부는 단호한 증거로 작업하는 것을 선호합니다 .- – paxdiablo

+0

@Hasturkun - 예 nfds는 0이고 창문에 있습니다. – whoi

답변

6

그건 맞지 않아요. 집합에있는 파일 설명자의 수를 0으로 지정할 수 있어야합니다. 사실, 이것은 초기에 타임 아웃 코드를 사용하는 것을 기억하며, 설명자가없는 select을 사용하고 타임 아웃 값을 적절하게 설정했습니다.

-1이 반환되면 문제가 무엇인지 확인하려면 errno을 확인해야합니다.


아 댓글에 따르면 WSAEINVAL은 WinSock을 의미합니다. 그것은 당신의 문제를 설명합니다. 이 시간 제한 값이 유효하지 않거나 세 가지 설명 변수가 null 인 경우 WSAEINVAL을 얻을 것이다

This page here 상태 :-) 우리 불행 넣어해야 끔찍한 짐승입니다. 나중에 FD_ZERO이 "집합을 null 세트로 초기화합니다"라고 나와 있습니다. 마지막 스 니펫은 매개 변수가 여전히 NULL로 간주되는지 여부를 나타내며, 나는 알지 못합니다. 귀하의 타임 아웃이 괜찮다고 가정하면 (세트 중 하나에 FD가있는 경우 작동하므로) 아마도 그럴 것입니다.

버클리 소켓은 NULL FD 세트 (즉, NULL 포인터)와 빈 FD 세트 (FD가 설정되지 않은 유효한 포인터)를 구별합니다. WinSock은 특히 nfds이 무시되므로 그다지 유용하지 않을 수 있습니다 버클리와의 호환성을 위해서만 포함되었습니다.

WinSock이 아마도 당신이하려는 일을하지 않을 것으로 예상됩니다 (비록 확실하지 않지만). 그것은 단지 여러분이 뭔가 잘못하고 있다고 가정하고 하나 이상의 FD 세트에있는 하나 이상의 소켓에 대해서만 select을 사용해야합니다 (FD가없는 select의 유일한 사용은 지연이고 Windows에는 많은 좋은 방법이 있기 때문에) 지연).

+0

사실 FD_ZERO로 0으로 초기화되었습니다. 선택하지만 어떻게 든 -1을 얻고 오류는 WSAEINVAL이지만 fd 세트를 읽으면됩니다.하지만 오류가 발생하지만 소켓을 설정하면 작동합니다 ... – whoi

+0

@paxdiablo - 아마도 맞을 것입니다. Windows (제대로 작동하지 않는 친구)는 fd 세트가 비어 있으면 무시합니다. – whoi

-1

select 도움말을 읽어보십시오. WSAEINVAL은 "타임 아웃 값이 유효하지 않거나 세 개의 설명자 매개 변수가 모두 null"인 경우 반환됩니다. . 잘못된 타임 아웃 값을 전달하는 것은 명백합니다. 따라서 0 개의 설명자를 사용하려면 올바른 시간 초과 값을 제공하십시오.

+0

사실 당신이 말한대로이 설명을 이미 읽었지만 NULL이 아닌 인수는 비어 있습니다 ... – whoi

+0

당신은 타임 아웃을 위해 무엇을 전달합니까? – Jay

+0

참고로, select call은 세 개의 설명자 세트 중 최소한 하나가 값을 가져야하거나 시간 초과 값이 적절해야한다고 생각합니다. select가 나오지 않을 수도 있습니다. 권리? 세 가지 설명자 매개 변수를 모두 NULL로 전달하고 잘못된 시간 제한을 언급하면 ​​select가 영원히 차단됩니다. – Jay

1

Windows에서 select 함수는 nfds 인수를 완전히 무시합니다. 현재 이것을 테스트 할 수는 없지만 모든 세트가 NULL이 아니지만 비어 있으면 오류가 반환 될 수 있습니다.

이 문제를 해결하려면 전체 선택을 건너 뛰거나 항상 소켓에 소켓이 하나 이상 있는지 확인하기 위해 더미 소켓을 유지하십시오.

+0

당신은 Windows에서 무시 무시한 nfds이지만, 내 인수가 NULL이 아닌 것입니다. 빈 .Windows는 NULL과 같은 위협이있는 것 같습니다. Bullsh .. – whoi

+0

리눅스가 Windows보다 훨씬 잘 처리합니다! 정확히 같은 params를 가진 select() 호출은 리눅스에서 0을 반환합니다. 또한 @Hasturkun, Windows 및 Linux에서이를 테스트했습니다. Windows에서 -1 (SOCKET_ERROR)을 반환한다고 보증합니다. –