2009-05-12 12 views
7

Mam aplikację C++, która używa standardowych wywołań gniazd i chcę wiedzieć, czy mogę stwierdzić, czy gniazdo jest nadal otwarte, bez wysyłania lub odbierania jakichkolwiek danych. Czy mogę wykonać niezawodny telefon select lub ioctlsocket?Jak mogę sprawdzić, czy gniazdo jest nadal otwarte?

+0

Czy masz na myśli sprawdzenie, czy gniazdo zostało zamknięte na drugim końcu? –

+0

Tak. Moja aplikacja działa w systemie Windows i jeśli komputer jest hibernowany, po jego powrocie gniazdo może przestać być poprawne, ponieważ drugi koniec je zamknął (a ponieważ moja aplikacja jest zawieszona, nie otrzymuję powiadomienia). – Rob

Odpowiedz

7

Jeśli spróbujesz odebrać jeden bajt, możesz otrzymać kilka błędów, jeśli masz gniazdo bez blokady i spróbować odebrać poprawne połączenie, otrzymasz błąd WSAEWOULDBLOCK.

Wiedząc o tym możemy sprawdzić non gniazdo blokady Podobnie jak

bool connected(SOCKET sock) 
{ 
    char buf; 
    int err = recv(sock, &buf, 1, MSG_PEEK); 
    if(err == SOCKET_ERROR) 
    { 
      if(WSAGetLastError() != WSAEWOULDBLOCK) 
      {return false;} 
    } 
    return true; 
} 

jak widać z return value of recv recv może powrócić timeout lub kilka innych błędów dla rozłączenia, wierzę WSAEWOULDBLOCK jest jedyną wartością może ona return, jeśli wystąpił błąd, ale nadal jest podłączony, ale możesz dwukrotnie sprawdzić listę zwracanych wartości. Również flaga używana w recv (MSG_PEEK) oznacza, że ​​dane są nadal w stanie odczytać, kiedy przejdziesz później, po sprawdzeniu, więc nie musisz się martwić o utratę jednego bajtu danych.

Wierzę, że to będzie działać dobrze tylko z nieblokującymi gniazdami, ponieważ może blokować, dopóki nie otrzyma danych. Jeśli chcesz użyć gniazda blokującego, przed jego sprawdzeniem możesz ustawić je jako niezablokowane przy użyciu ioctlsocket, a następnie przywrócić je do stanu, w którym się on znajdował.

+0

Do blokowania gniazd używaj select. –

3

Gniazdo "otwarte" nie pomaga w łączeniu typu end-to-end. Jedynym sposobem, by wiedzieć na pewno, że możesz komunikować się z drugim końcem, jest porozumiewanie się z drugim końcem.

W każdym opracowanym protokole powinieneś pomyśleć o wprowadzeniu tego zachowania sprawdzającego. Jeśli nie jest to twój protokół, czasami można to zrobić podstępnie (na przykład FTP w bardzo małym, bezużytecznym pliku, aby sprawdzić, czy porty FTP są nadal otwarte).

Powiązane problemy