2010-06-18 9 views
107

3 domande:Qual è la differenza tra la connessione e il timeout di lettura per i socket?

  1. Qual è la differenza tra connessione e leggere timeout per i socket?

  2. Che cosa significa timeout impostato su "infinito"? In quale situazione può rimanere in un ciclo infinito? e cosa può innescare la morte del ciclo infinito?

  3. Cosa significa "" read time impostato su "infinito"? In quale situazione può rimanere in un ciclo infinito? e cosa può innescare la morte del ciclo infinito?

risposta

135

1) Qual è la differenza tra connessione e timeout lettura per i socket?

Il timeout della connessione è il timeout durante la connessione iniziale; Completando l'handshake della connessione TCP. Il timeout di lettura è il timeout in attesa di leggere i dati. In particolare, se il server non riesce a inviare un byte < timeout> secondi dopo l'ultimo byte, verrà generato un errore di timeout di lettura.

2) Che cosa significa timeout di connessione impostato su "infinito"? In quale situazione può rimanere in un ciclo infinito? e cosa può innescare la morte del ciclo infinito?

Significa che il tentativo di connessione può potenzialmente bloccare per sempre. Non esiste un ciclo infinito, ma il tentativo di connessione può essere sbloccato da un altro thread che chiude il socket. (A Thread.interrupt() chiamata può anche fare il trucco ... non sono sicuro.)

3) Cosa impostato timeout leggere su "infinito" significa? In quale situazione può rimanere in un ciclo infinito? e cosa può innescare la morte del ciclo infinito?

Significa che una chiamata a read sul flusso di socket potrebbe bloccare per sempre. Ancora una volta non esiste un ciclo infinito, ma lo read può essere sbloccato da una chiamata Thread.interrupt(), chiudendo il socket e (ovviamente) dall'altra parte che invia dati o chiude la connessione.

+0

"Il timeout di lettura è il timeout in attesa di leggere i dati.". Hai scritto "WAITING" per leggere i dati? Il timeout di lettura non è il tempo per quanto tempo il socket può essere aperto? – corgrath

+0

In Java è possibile impostare "infinito" sulla connessione e leggere il timeout. Mi chiedo come possano accadere queste situazioni (dove sarà in un loop infinito). Se dici che la connessione è per l'handshake TCP, come può l'attesa essere infinita? Non sono stati accettati tutti i pacchetti in TCP? – corgrath

+4

"Il timeout di lettura non è il tempo di apertura del socket?" È corretto. "Non tutti i pacchetti in TCP sono connessi?" Il timeout indica il tempo di attesa per l'altra estremità per inviare un SYN-ACK in risposta ai pacchetti SYN iniziali. –

6

Questi sono valori di timeout imposti da JVM per la creazione della connessione TCP e in attesa di lettura dei dati dal socket.

Se il valore è impostato su infinito, non si attenderà per sempre. Significa semplicemente che JVM non ha timeout e che il sistema operativo sarà responsabile di tutti i timeout. Tuttavia, i timeout sul sistema operativo potrebbero essere molto lunghi. Su alcune reti lente, ho visto timeout fino a 6 minuti.

Anche se si imposta il valore di timeout per il socket, potrebbe non funzionare se il timeout si verifica nel codice nativo. Possiamo riprodurre il problema su Linux collegandoci a un host bloccato dal firewall o scollegando il cavo sullo switch.

L'unico approccio sicuro per gestire il timeout TCP è eseguire il codice di connessione in un thread diverso e interrompere il thread quando richiede troppo tempo.

+0

"Se il valore è impostato su infinito, non si attenderà per sempre." Finché non si tratta di discutere sul significato di "infinito", può capitare di certo che aspetti molto a lungo. Abbiamo avuto un caso qui, dove un 'HttpURLConnection.getResponseCode()' era sospeso per apprx. una settimana fino al riavvio del processo. Ovviamente non c'era nessun timeout impostato sul lato JVM e nemmeno un timeout sul lato del sistema operativo Linux. –

+0

Il paragrafo finale non è corretto. Una connessione si interromperà al massimo dopo circa un minuto. Un thread separato è completamente inutile. Puoi certamente * leggere * che funziona per sempre se non ci sono dati. Tuttavia, Javadoc ha torto sul fatto che il timeout di connessione predefinito sia infinito. Non lo è. – EJP

+1

@comeGetSome Non è corretto. È possibile spegnere il socket per l'input. Ciò farà sì che la lettura bloccata incontri la fine del flusso. – EJP

Problemi correlati