TcpClient продолжает посылку некоторое время, даже если нет соединения - PullRequest
0 голосов
/ 13 июля 2011

Фон / Платформа:

.NET 4 / C #

У меня есть 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 не должен немедленно завершиться ошибкой, если хост не отвечает?

Как обнаружить , что питание устройства было отключено и что соединение больше не действует?

1 Ответ

1 голос
/ 13 июля 2011

Вы не можете.Как бы вы обнаружили это, если между вами есть коммутатор / маршрутизатор?Ваш компьютер все еще полностью подключен.

TCP / IP работает таким образом.Существует несколько повторных (обычно с увеличением таймаута) пакетов, которые не подтверждены получателем.Значения времени ожидания и количество повторных посылок зависят от конкретной реализации вашего tcp-стека / операционной системы.

Свойство TcpClient.SendTimeout контролирует только время, необходимое для дальнейшей отправки данных вниз поstream.

После вызова метода Write базовый сокет возвращает количество байтов, фактически отправленных хосту.Свойство SendTimeout определяет количество времени, которое TcpClient будет ожидать, прежде чем получит количество возвращенных байтов.Если время ожидания истекает до успешного завершения метода Send, TcpClient генерирует исключение SocketException.По умолчанию тайм-аут не установлен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...