2013-05-15 8 views
5

Używam boost::asio dla aplikacji serwer/klient. Serwer akceptuje tylko jedno połączenie naraz. Zastanawiam się, jaki jest najlepszy sposób, aby serwer zweryfikował, czy klient jest nadal podłączony.Zwiększ ASIO: Jak serwer może wiedzieć, czy klient jest nadal podłączony?

Celem tego jest to, że chciałbym wiedzieć, czy klient się zawiesił, aby móc ponownie zacząć słuchać nowych prób połączenia.

+0

Potrzebujesz bicia serca na poziomie aplikacji - nie ma innego niezawodnego sposobu. –

Odpowiedz

3

W mojej aplikacji używam następujących flag, a mój odczyt pojawia się, gdy klient się rozłącza. Spróbuj, jeśli jest to w twojej aplikacji. Zastosuj te flagi tuż po połączeniu.

w moim przypadku skt_TCP jest typu boost::asio::ip::tcp::socket

int32_t accept_server_socket = skt_TCP.native_handle(); 

int32_t timeout = 8; 
int32_t cnt = 2; 
int32_t intverval = 2; 

// Added Keepalive flag 
boost::asio::socket_base::keep_alive opt_keep_alive(true); 
skt_TCP.set_option(opt_keep_alive); 
setsockopt(accept_server_socket, SOL_TCP, TCP_KEEPIDLE, &timeout, sizeof(timeout)); 
setsockopt(accept_server_socket, SOL_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)); 
setsockopt(accept_server_socket, SOL_TCP, TCP_KEEPINTVL, &intverval, sizeof(intverval)); 
0

To naprawdę zależy od wybranego protokołu.

Prosty protokół poleceń

Jeśli protokół serwer zawsze czeka na wiadomość od klienta, będziesz zawsze mieć w oczekiwaniu async_read dla każdego klienta podłączonego. Powinno to powrócić z błędem (EOF), gdy klient rozłącza się w jakikolwiek sposób.

Zachowanie przy życiu jest podejściem, jak wspomniano powyżej, ale oczekuje na prace async_read dobrze w tym celu.

Prosty protokół zdarzenia

Prosty protokół wydarzenie wiąże klienta nasłuchiwania danych i serwera wysyłającego go. W tym protokole serwer nie ma pojęcia, czy klient istnieje, ponieważ klient akceptuje tylko dane i nadal czeka. Klient nigdy nie wysyła do serwera żadnej wiadomości.

Prezentuje wymóg utrzymania przy życiu. async_write operacje nie kończą się niepowodzeniem w taki sam sposób, jak robią to async_read, gdy klient jest już rozłączony.

Istnieją inne opcje, takie jak posiadanie na serwerze zawsze oczekującej operacji async_read, która próbuje odczytać 1 bajt. To się nie powiedzie, gdy klient rozłączy się podobnie do powyższej dyskusji na temat prostego protokołu, ale nigdy się to nie uda, ponieważ klient nie wysyła danych przez prosty protokół zdarzeń.