03.10.2018 Socket KeepAlive или формирование второго канала передачи данных.
 
Коллеги, доброго дня.

Есть клиент-серверное приложение. С одной стороны выполняется Socket.Send, с другой — Socket.Receive. Всё это обёрнуто в NetworkStream с кучей обёрток поверх, но это уже не важно.

В один прекрасный момент пропадает связь между клиентом и сервером. В этот момент отправитель отваливается на Socket.Send и закрывает коннекцию — информация о закрытии коннекции теряется. По этой причине получатель ничего не знает о том, что данных не будет и продолжает висеть.

Спустя пару секунд сеть восстанавливается. Спустя ещё минуту начинают ходить кипалайвы. Но поскольку сеть и сокеты с обеих сторон живы, они успешно сигнализируют о том, что сетка жива.

Проблема в том, что в протокол не заложена информация об изменении состояния запроса и отсутствует подтверждение доставки. Чтобы не ломать обратную совместимость и избавить себя от необходимости вкручивать различные таймауты на каждую операцию и механизмы их анализа для ретраев, хочется заиметь способ ручного управления кипалайвами. Раз в минуту поток из пула посылает в канал KeepAlive'а пакет. Если за 10 минут по каналу KeepAlive'а не пришло ни одного пакета, соединение рубится.

И вот тут встаёт вопрос — а как получить этот второй канал передачи? Out-of-band data вычеркиваем — любой роутер без поддержки разломает столь изящное решение. Windows 95 вообще уходила от них в синьку. Не знаю, изменилось ли что-нибудь в лучшую сторону с тех пор. Что ещё можно сделать? Как получить второй, независимый канал передачи данных, имея на руках только подключённый Socket?

Повторное подключение не подходит — переделок будет столько, что проще сразу сделать хорошо. Сразу делать хорошо сейчас не хочется. Ищу адекватный костыль.

Спасибо за любые идеи.