Вам необходимо явно сообщить WinSock, что вы не хотите, чтобы он очистился для вас после закрытия сокета. Это делается установкой LingerState
следующим образом:
socket.LingerState = new LingerOption(true, 0);
socket.Close();
LingerState
немного сбивает с толку, потому что если вы отключите задержку, WinSock на самом деле задержит , но не заблокирует вашу программу. Вы должны включить задержку и установить время ожидания на ноль, чтобы заставить WinSock разорвать соединение.
P.S. Если вам нужна информация о пакетах keepalive (heartbeats), Я написал запись в блоге на эту тему .
Обновление:
Я перечитал ваш вопрос (и прокомментировал), и мой ответ неправильный ...
Код выше будет имитировать аварийное закрытие, а не полуоткрытое положение. В программном обеспечении нет способа имитировать полуоткрытую ситуацию; вам нужно отсоединить кабель Ethernet, который не подключен ни к одному компьютеру, чтобы проверить это (например, протяните кабель между двумя коммутаторами в этой конфигурации: компьютер A <-> коммутатор <-> коммутатор <-> компьютер B).