2012-08-01 2 views
7

Sto lavorando a un'applicazione in cui un client si connette a una connessione TCP che quindi attiva una quantità di lavoro che potrebbe richiedere molto tempo per il completamento. Questo lavoro deve essere annullato se l'utente interrompe la connessione TCP.La scrittura di zero byte su un flusso di rete è un modo affidabile per rilevare connessioni chiuse?

Attualmente, quello che sto facendo è di avviare un timer che controlla periodicamente le reti di flussi di connettività in questo modo:

// stream is a Stream instance 
var abort = false; 
using (new Timer(x => { 
    try 
    { 
     stream.Write(new byte[0], 0, 0); 
    } 
    catch (Exception) 
    { 
     abort = true; 
    } 
}, null, 1000, 1000)) 
{ 
    // Do expensive work here and check abort periodically 
} 

mi sarebbe piaciuto leggere il CanWrite, CanRead o Connected ma riportano la ultimo stato del flusso. Scrivere zero byte è un modo affidabile per testare la connettività, oppure può causare problemi di per sé? Non riesco a scrivere o leggere alcun dato reale sullo stream poiché ciò potrebbe rovinare il client.

risposta

3

Diciamo solo che l'ho saputo funzionare, decenni fa, ma non esiste una ragione intrinseca per cui dovrebbe. Qualsiasi degli strati API tra voi e lo stack TCP ha il diritto di sopprimere la chiamata al livello immediatamente inferiore, e anche se si arriva fino in fondo alla pila che verrà restituire solo un errore se:

  1. controlla per errori di rete prima di verificare la lunghezza zero, che dipende dall'implementazione, e
  2. Si è verificato già un errore di rete, causato da un'operazione precedente o un RST in arrivo.

Se ti aspetti che riesca a sondare magicamente la rete fino all'altra estremità, sicuramente non lo farà.

+0

Sembra funzionare per me, ma posso vedere il tuo punto. Non mi aspetto di sondare fino in fondo, ma se fosse andato un po 'probabilmente sarebbe stato abbastanza buono. Da qualche parte ci deve essere una sorta di bandiera nativa che dice se c'è stata una connessione di reset però? Un evento o qualcosa sarebbe davvero bello. – Dervall

+0

@Dervall Lo stack sa se c'è stato un reset, ma non ho mai visto un'API TCP nella mia vita che glielo avrebbe dato. Devi fare I/O su una connessione TCP per ottenere errori. È davvero progettato in questo modo: 'nessun segnale di linea'. Costruito per sopravvivere ai guasti dei nodi intermedi e al re-routing. – EJP