2012-03-29 11 views
6

Używam Boost :: asio do implementacji aplikacji klient/serwer. Poniższy kod klienta służy do łączenia się ze zdalnym serwerem.Jak sprawdzić, czy połączenie z gniazdem znajduje się pod napięciem w Boost :: asio?

try 
    { 
     boost::asio::io_service   m_io_service; 
     boost::asio::ip::tcp::socket m_socket(m_io_service); 
     boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 17); 
     m_socket.connect(endpoint); 
    } 
    catch (std::exception& e) 
    { 
     std::cerr << e.what() << std::endl; 
    } 

Po stronie klienta chcę sprawdzić, czy połączenie jest aktywne. Funkcja "m_socket.is_open();" nie działa. Gdy gniazdo serwera zostanie zamknięte, "m_socket.is_open();" nadal zwraca wartość true po stronie klienta. Czy istnieje sposób sprawdzenia połączenia?

+1

Miałem podobną wątpliwość tutaj: http://stackoverflow.com/q/1511129/174605 i istnieje drobna odpowiedź od joshperry – coelhudo

Odpowiedz

2

Z powodu ograniczenia podstawowego interfejsu gniazda, nie ma możliwości zaimplementowania funkcji takiej jak isConnected w celu sprawdzenia statusu połączenia TCP na poziomie gniazda. Myślę o obejściu tego problemu.

W mojej implementacji buforuję flagę statusu połączenia (bool m_IsConnected) w mojej aplikacji. Ta flaga służy do oznaczenia statusu połączenia. Zakłada się, że jeśli nie ma błędu z gniazda, połączenie TCP jest żywe.

Flaga będzie aktualizowana za każdym razem, gdy używasz gniazda. Jeśli występują błędy podczas wysyłania i odczytu danych, oznacza to, że połączenie jest rozłączone. Następnie odpowiednio zmień flagę. Jeśli połączenie TCP jest bezczynne przez dłuższy czas. Ta flaga nie odzwierciedla rzeczywistego stanu połączenia TCP przed użyciem gniazda. Na przykład gniazdo jest bezczynne przez długi czas. Jest odłączony z powodu słabej sieci. W tym przypadku m_IsConnected jest nadal prawdziwe, ponieważ nie otrzymujemy żadnego połączenia zwrotnego dotyczącego zdarzenia rozłączenia. Podczas próby wysłania danych przez to gniazdo wystąpi błąd. A teraz wiemy, że połączenie jest rozłączone.

0

Jest to ograniczenie podstawowego interfejsu gniazda (myślę, że zarówno dla Winsock/Bekerly). Możesz wymyślić wiadomość specjalnie do tego celu, na którą serwer odpowiada, jeśli żyje. Inaczej, jeśli masz timeout, oznacza, że ​​połączenie jest wyłączone.

EDYCJA: Jak zauważył Joachim, próba odczytania gniazda może być lepszym sposobem.

+3

Próba wysłania do połączenia, które zostało zamknięte, spowoduje błąd, nawet jeśli to było czyste i właściwe zamknięcie. Próbowanie _read_ z gniazda daje lepszy trop o tym, jak gniazdo zostało zamknięte (tzn. 'Read' lub' recv' zwraca zero dla czystego zamknięcia lub błędu, gdy wystąpi błąd). –

+0

Ach tak masz rację, I zapomniałem, że możesz to przeczytać. Zaktualizuje powyższą odpowiedź. – Rolle

+0

Funkcja free boost :: asio :: read może być użyta do odczytu gniazda. Myślę, że jest efekt uboczny, jeśli za pomocą funkcji odczytu wykryje stan połączenia. Odczytuje dane ze strumienia gniazd, czego nie chcę w funkcji wykrywania statusu. Ponadto, jeśli połączenie jest aktywne, funkcja odczytu blokuje. – Jeffrey

Powiązane problemy