2012-08-01 12 views
7

Pracuję nad aplikacją, w której klient łączy się z połączeniem TCP, co powoduje uruchomienie pracy, która może zająć dużo czasu. Ta praca musi zostać anulowana, jeśli użytkownik zrezygnuje z połączenia TCP.Czy zapisywanie zerowych bajtów w strumieniu sieci jest niezawodnym sposobem wykrywania zamkniętych połączeń?

Obecnie, co robię jest uruchamiany czasomierz, który okresowo sprawdza łączność przez sieć strumieni ten sposób:

// 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 
} 

bym lubił czytać CanWrite, CanRead lub Connected ale w sprawozdaniu ostatni status strumienia. Czy zapisanie zerowego bajtu jest niezawodnym sposobem testowania łączności, czy może to samo powoduje problemy? Nie mogę pisać ani czytać żadnych prawdziwych danych w strumieniu, ponieważ mogłoby to zepsuć klienta.

Odpowiedz

3

Powiedzmy, że wiedziałem, że działa, dekady temu, ale nie ma żadnego wewnętrznego powodu, dla którego powinien. Dowolna warstwa interfejsu API między tobą a stosem TCP ma prawo do wyłączenia wywołania następnej warstwy w dół, a nawet jeśli zostanie przeniesiona do stosu, zwróci tylko błąd, jeśli:

  1. Sprawdza dla błędów sieci przed sprawdzeniem długości zerowej, która jest zależna od implementacji, i
  2. Wystąpił już błąd sieci, spowodowany przez jakąś poprzednią operację lub przychodzący RST.

Jeśli spodziewacie się, że magicznie sonduje sieć do końca, to na pewno nie.

+0

Wydaje się, że działa dla mnie, ale widzę twój punkt widzenia. Nie spodziewam się, że to sonduje do końca, ale gdyby poszło trochę dalej, prawdopodobnie byłby wystarczająco dobry. Gdzieś musi być jakaś rodzima flaga, która mówi, że jeśli zostało zresetowane połączenie? Wydarzenie lub coś byłoby naprawdę miłe. – Dervall

+0

@Dervall Stos wie, czy nastąpił reset, ale nigdy nie widziałem w moim życiu interfejsu TCP API, który by ci go dał. Musisz wykonać operacje we/wy dla połączenia TCP, aby uzyskać błędy. Jest naprawdę zaprojektowany w ten sposób: "brak sygnału wybierania". Zbudowany, aby przetrwać awarie węzłów pośrednich i zmianę trasy. – EJP