2016-08-23 11 views
7

Mam wywołanie blokujące accept() w wątku oczekującym na żądania połączenia. Gdy aplikacja ma się zamknąć, chcę zasygnalizować wątek oczekujący na accept(), aby wyjść z wdziękiem. Znalazłem w dokumentacji dla Winsock, że mogę ustawić wartość limitu czasu dla send() i recv(), ale nie mogę tego zrobić dla accept().Jak wyjść z funkcji blokowania accept() w systemie Windows?

Przeczytałem, że mogę sprawić, że gniazdo nie będzie blokować i używać select() i przekazać wartość limitu czasu dla select(), ale szukam rozwiązania dla blokowania gniazd.

+0

AFAIK nie można ... a przynajmniej nie "starszych" (pre-Vista)? Windows. –

+1

Nie musisz przełączać się na opcję bez blokowania, aby użyć opcji 'select()', można jej również używać z gniazdami blokującymi. Wywołaj 'select()' z limitem czasu i nie wywołuj 'accept()', chyba że 'select()' mówi, że połączenie oczekuje na akceptację. W przeciwnym razie tak, przełącz się na nieblokowanie. Możesz użyć 'WSAEventSelect()' z 'WSAWaitForMultipleEvents()', aby oczekiwać na zdarzenia gniazda i zdarzenie zakończenia w tym samym czasie. Lub użyj portu zakończenia we/wy dla zdarzeń gniazd i w razie potrzeby umieść zdarzenie zakończenia. –

+0

CancelSynchronousIo() może również być szybką i łatwą łatką. –

Odpowiedz

1

Czytałem, że mogę zrobić gniazda nieblokujące i użyć select() i przekazać wartość limitu czasu dla select(), ale szukam roztwór do blokowania gniazd.

Można to zrobić na gnieździe blokującym:

sock = socket(...); 
bind(sock, ...); 
listen(sock, ...); 

while (program_running()) 
{ 
    timeval timeout = {1, 0}; 
    fd_set fds; 
    FD_ZERO(&fds); 
    FD_SET(sock, &fds); 

    select(sock+1, &fds, NULL, NULL, &timeout); 

    if (FD_ISSET(sock, &fds)) 
    { 
     client = accept(sock, ...); 

     // do things with client 
    } 

Od MSDN accept function documentation:

The readfds parametrów identyfikuje gniazd, które mają być sprawdzane pod kątem czytelności. Jeśli gniazdo znajduje się obecnie w stanie nasłuchiwania, zostanie oznaczone jako odczytywane, jeśli odebrano przychodzące żądanie połączenia, aby zagwarantować, że akceptacja zakończy się bez blokowania.