2009-05-04 3 views
5

Qual è il modo più semplice per verificare se un socket è stato chiuso sul lato remoto della connessione? socket::is_open() restituisce true anche se è chiuso sul lato remoto (sto usando boost::asio::ip::tcp::socket).Come verificare se il socket è chiuso in Boost.Asio?

Potrei provare a leggere dal flusso e vedere se ha successo, ma dovrei cambiare la logica del mio programma per farlo funzionare in questo modo (non voglio che i dati vengano estratti dallo stream al punto del controllo).

+0

Perché è necessario sapere se la connessione remota è stata chiusa? – outis

+0

Inoltre, stai usando un protocollo applicativo di tua progettazione o un protocollo standard? – outis

+0

Sto scrivendo un programma di chat di base e devo informare l'utente che l'altra persona ha chiuso l'app. Ho il mio protocollo e ho già aggiunto un messaggio "Chiudi". L'unico inconveniente è che non viene inviato se l'app viene uccisa/si blocca/ecc. – Hali

risposta

4

Se la connessione è stata chiusa correttamente dal peer, è necessario ottenere un EOF durante la lettura. Altrimenti generalmente faccio ping per capire se la connessione è veramente viva.

+1

... e ho bisogno di leggere per ottenere l'EOF. Immagino che non ci sia modo di aggirare allora. Grazie! – Hali

7

È disponibile una funzione di aumento della luminosità? La maggior parte delle implementazioni socket ha un modo di leggere i dati senza rimuoverli dalla coda, quindi è possibile leggerli nuovamente in seguito. Questo sembrerebbe soddisfare le tue esigenze.

Dopo aver guardato rapidamente i documenti asio, non sono riuscito a trovare esattamente quello che mi aspettavo, ma questo non significa che non sia lì.

Suggerisco this per i principianti.

+0

Sì, hai ragione. Puoi passare un flag al metodo "receive" che dice di non rimuovere i dati. Stavo usando il metodo "read_some", che non ha questo argomento flag. Grazie per segnalarlo! – Hali

+0

supponiamo di aver impostato il socket e la risposta, quindi puoi impostare uno stream, ad es. std :: istream myhttpstream (& presponse); e quindi puoi usare la funzione std :: istream :: peek(). –

+0

Faccio questo: ricevuto = socket(). Receive (boost :: asio :: buffer (buf), tcp :: socket :: message_peek); –

1

Penso che in generale una volta aperto un socket, si dovrebbe iniziare a leggerlo immediatamente e non smettere mai di farlo. In questo modo puoi rendere il tuo server o client in grado di supportare sia i protocolli sincroni che asincroni. Nel momento in cui il client chiude la connessione, nel momento in cui la lettura ti dirà questo.

0

L'utilizzo di error_code è in grado di verificare la condizione se il client è connesso o meno. Se la connessione è riuscita, error_code error.value() restituirà 0, altrimenti restituirà un altro valore. Puoi anche controllare il messaggio() da error_code.

7

Verificare l'errore boost::asio::error::eof nel gestore async_receive. Significa che la connessione è stata chiusa. Questo è l'unico modo corretto per farlo.