GNU/Linux >> Linux Esercitazione >  >> Linux

Come utilizzare correttamente l'opzione SO_KEEPALIVE per rilevare che il client all'altra estremità è inattivo?

Per modificare il numero di probe o gli intervalli di probe, scrivi i valori nel filesystem /proc come

 echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time
 echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl
 echo 20 > /proc/sys/net/ipv4/tcp_keepalive_probes

Tieni presente che questi valori sono globali per tutti i socket abilitati keepalive sul sistema. Puoi anche sovrascrivere queste impostazioni in base al socket quando imposti setsockopt, vedi la sezione 4.2 del documento che hai collegato.

Non puoi "controllare" lo stato del socket dallo spazio utente con keepalive. Invece, il kernel è semplicemente più aggressivo nel forzare l'estremità remota a riconoscere i pacchetti e determinare se il socket è andato male. Quando tenti di scrivere sul socket, otterrai un SIGPIPE se keepalive ha determinato che l'estremità remota è inattiva.


Otterrai lo stesso risultato se abiliti SO_KEEPALIVE, come se non abiliti SO_KEEPALIVE - in genere troverai il socket pronto e riceverai un errore quando lo leggi.

È possibile impostare il timeout keepalive su base per socket in Linux (questa potrebbe essere una funzionalità specifica di Linux). Lo consiglierei piuttosto che modificare l'impostazione a livello di sistema. Vedi la pagina man di tcp per maggiori informazioni.

Infine, se il tuo client è un browser Web, è molto probabile che chiuderà comunque il socket abbastanza rapidamente:la maggior parte di essi manterrà solo connessioni keepalive (HTTP 1.1) aperte per un tempo relativamente breve (30 secondi, 1 minuto ecc.). Ovviamente se la macchina client è scomparsa o la rete non funziona (che è ciò che SO_KEEPALIVE è davvero utile per rilevare), allora non sarà in grado di chiudere attivamente il socket.


Come già discusso, SO_KEEPALIVE rende il kernel più aggressivo nel verificare continuamente la connessione anche quando non stai facendo nulla, ma non modificare o migliorare il modo in cui le informazioni vengono fornite all'utente. Lo scoprirai quando proverai a fare effettivamente qualcosa (per esempio "scrivere"), e lo scoprirai subito dato che il kernel ora riporta solo lo stato di un flag impostato in precedenza, invece di dover aspettare qualche secondi (o molto di più in alcuni casi) per il fallimento dell'attività di rete. Verrà comunque utilizzata la stessa logica di codice che avevi per gestire la condizione "l'altro lato è andato via inaspettatamente"; ciò che cambia è la tempistica (non il metodo).

Praticamente ogni programma socket "pratico" in qualche modo fornisce non -bloccare l'accesso ai socket durante la fase dati (forse con select()/poll(), o forse con fcntl()/O_NONBLOCK/EINPROGRESS&EWOULDBLOCK, o se il tuo kernel lo supporta forse con MSG_DONTWAIT). Supponendo che ciò sia già stato fatto per altri motivi, è banale (a volte non richiede alcun codice) inoltre scoprire subito l'interruzione della connessione. Ma se la fase dati non forniscono già in qualche modo un accesso non bloccante ai socket, non scoprirai la caduta della connessione fino alla prossima volta che proverai a fare qualcosa.

(Una connessione socket TCP senza una sorta di comportamento non bloccante durante la fase dati è notoriamente fragile, poiché se il pacchetto sbagliato incontra un problema di rete è molto facile per il programma "bloccarsi" indefinitamente, e non c'è molto che tu può fare al riguardo.)


Linux
  1. Come usare il comando Linux grep

  2. Come usare il comando cronologia in Linux

  3. Come utilizzare il comando basename?

  4. Come utilizzare il comando id in Linux

  5. Come trovare l'altra estremità della connessione socket unix?

Come utilizzare il comando superiore in Linux

Come utilizzare il comando Ping di Linux

Come usare il comando nmap

Come utilizzare il comando fd sul sistema Linux

Come utilizzare il comando wget in Linux?

Come usare il comando xargs in Linux?