@Vermut756

Почему может рваться TCP-подключение без видимых причин?

Сервер (TcpListener) слушает клиента (бесконечный цикл, в потоке).
Единственный клиент (TcpClient) слушает сервер (бесконечный цикл, в потоке).
Оба цикла висят на вызове Read(), так как ни сервер ничего не пишет клиенту, ни клиент - серверу.
Оба приложения консольные. Больше ничего не выполняется.
Сервер находится на VPS, клиенты разные были, от этого ничего не меняется.

Проблема, собственно, в том, что спустя так полчаса простоя, у сервера Read вдруг вылетает в Exception, обычно так бывает если клиент рвет подключение.
Такое бывает если убить процесс клиента, но он цел.

Думал, что дело может быть в кратковременном пропадании подключения к интернету. На клиенте отключался от сети, затем подключался. Ничего подобного - все работает.

Какие еще версии?

Сам Exception пока не смотрел, не было возможности, я по глупости сделал try catch который его "проглатывал" и выводил только сухое сообщение в лог. На локалхосте пока не пробовал. Все это я буду делать, но надеюсь что вы поможете.
  • Вопрос задан
  • 2123 просмотра
Пригласить эксперта
Ответы на вопрос 3
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Скорее всего вылетает по таймауту. Попробуйте включить keepalive
socket.SetSocketOption(SocketOptionLevel.Socket, 
                       SocketOptionName.KeepAlive, true );
Ответ написан
alsopub
@alsopub
Не зря же в некоторых программах типа мессенджеров была опци "поддерживать соединение" которая периодически отправляла не значащие в рамках протокола пакеты.
Upd https://habrahabr.ru/company/intersystems/blog/155565/
Ответ написан
Комментировать
Проблема может быть в том, что между клиентом и сервером NAT и на роутере из-за неактивности "протухает" запись в таблице NAT. Но решение, которое подсказали выше (keep-alive) поможет и в данном случае, только помимо собственно keep-alive'а необходимо установить keep-alive timeout секунд в 300 хотя бы, т.к. дефолтное значение (обычно 7200 секунд) вас не спасет. Т.е. помимо SO_KEEPALIVE необходимо установить TCP_KEEPIDLE/SIO_KEEPALIVE_VALS в зависимости от системы. В качестве альтернативы вы можете предусмотреть отправку keep-alive пакетов на уровне прикладного протокола. Обычно протоколы, рассчитанные на длинные соединения с небольшим трафиком, например мессенджеры, используют именно протокольные keep-alive.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы