Предыстория/платформа:
.NET 4/С#
У меня есть C# TcpClient
, который подключается к встроенному устройству через Ethernet. Я использую два таймера: один для хранения полученных данных в локальном Queue<MyMessage>
, а другой для отправки данных из другого Queue<MyMessage>
на встроенное устройство по TCP. Оба они запускаются каждые 200 ms
и отправляют/читают все, что им нужно отправить/прочитать.
Есть еще один таймер, который отправляет пакет проверки активности every second
(в настоящее время только в целях отладки).
Сценарий/проблема
После установления соединения встроенное устройство начинает отправлять какие-то данные на мой TcpClient
. Это работает как задумано (см. в журнале сообщений ниже). Однако затем я выключаю устройство (чтобы оно вообще не работало). Это означает, что он даже не может корректно закрыть TCP. Но это нормально. Я хочу проверить, что произойдет, если что-то подобное произойдет в реальной ситуации.
Однако TcpClient по-прежнему продолжает отправлять данные, даже если сервер (устройство) больше не находится в сети.
Вот код для отправки (используя NetworkStream.Write
):
while (messagesToSend.Count > 0)
{
MyMessage msg = messagesToSend.Dequeue();
clientStream.Write(msg.Data, 0, msg.Data.Length);
Debug.WriteLine(DateTime.Now.ToString() + " Sent: " + msg.MessageID);
}
Отправка идет еще секунд 45-50 и наконец обрывается. Это параметры, установленные для TcpClient и NetworkStream.
client.LingerState = new LingerOption(true, 0);
client.NoDelay = true;
client.SendTimeout = 3000;
clientStream.WriteTimeout = 3000;
И вот вывод отладки:
16:32:02 Connecting
16:32:02 Authorizing
16:32:02 Sent: 255
16:32:02 Sent: 0
16:32:02 Authorized
16:32:02 Connected
16:32:02 Received: 255
16:32:02 Received: 226
...
... some regular communication here
...
16:32:06 Received: 251
16:32:06 Sent: 0
16:32:07 Received: 251
16:32:07 Sent: 0 // At this point I have turned off the device
16:32:08 Sent: 0
16:32:09 Sent: 0
...
... every second the same message
...
16:32:54 Sent: 0
16:32:55 Sent: 0
16:32:56 Sent: 0
16:32:57 Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.
16:32:57 CommunicationError
Почему соединение так долго понимает, что оно закрыто? Разве NetworkStream.Write
не должен немедленно выйти из строя, если хост не отвечает?
Как обнаружить, что питание устройства отключено и что соединение больше не действует?