Почему может рваться TCP-подключение без видимых причин?
Скорее всего вылетает по таймауту. Попробуйте включить keepalivesocket.SetSocketOption(SocketOptionLevel.Socket, 
                       SocketOptionName.KeepAlive, true );
Проблема может быть в том, что между клиентом и сервером NAT и на роутере из-за неактивности "протухает" запись в таблице NAT. Но решение, которое подсказали выше (keep-alive) поможет и в данном случае, только помимо собственно keep-alive'а необходимо установить keep-alive timeout секунд в 300 хотя бы, т.к. дефолтное значение (обычно 7200 секунд) вас не спасет.  Т.е. помимо SO_KEEPALIVE необходимо установить TCP_KEEPIDLE/SIO_KEEPALIVE_VALS в зависимости от системы. В качестве альтернативы вы можете предусмотреть отправку keep-alive пакетов на уровне прикладного протокола. Обычно протоколы, рассчитанные на длинные соединения с небольшим трафиком, например мессенджеры, используют именно протокольные keep-alive.