Подтвердить что ты не робот

Как правильно и полностью закрыть /reset соединение TcpClient?

Каков правильный способ закрыть или reset соединение TcpClient? У нас есть программное обеспечение, которое общается с оборудованием, но иногда что-то идет не так, и мы больше не общаемся с ним, пока не перезапустим программное обеспечение.

Я попытался заставить TcpClient.Close() и даже установить его в null, но это не работает. Выполняется только полный перезапуск программного обеспечения.

Предложения?


Я не могу использовать ключевое слово using, потому что TpcClient определяется только в одном месте, но используется во всей библиотеке. (И есть только одно соединение в любой момент времени)

Это библиотека, которая обрабатывает связь. Само программное обеспечение может вызывать метод ResetConnection() класса Controller (который представляет собой аппаратное обеспечение).

В настоящее время он выглядит как

if (tcpClient != null)
{
    tcpClient.Close();
    tcpClient = null;
}

Теперь из того, что я прочитал здесь, я должен использовать tcpClient.Dispose() вместо "= null"

Я дам эту попытку и посмотрю, имеет ли это значение.

4b9b3361

Ответ 1

Вы должны закрыть поток перед закрытием соединения:

tcpClient.GetStream().Close();
tcpClient.Close();

Закрытие клиента не закрывает поток.

Ответ 2

Учитывая, что принятый ответ устарел, и я ничего не вижу в других ответах по этому поводу, я создаю новый. В .Net 2 и более ранних версиях вам пришлось вручную закрывать поток перед закрытием соединения. Эта ошибка исправлена во всех более поздних версиях TcpClient на С#, и, как указано в документе о методе Close, вызов метода Close закрывает как соединение, так и поток

РЕДАКТИРОВАТЬ в соответствии с Microsoft Docs

Метод Close помечает экземпляр как удаленный и запрашивает, чтобы соответствующий сокет закрыл TCP-соединение. Основываясь на свойстве LingerState, TCP-соединение может оставаться открытым некоторое время после вызова метода Close, когда данные еще предстоит отправить. Уведомление не предоставляется, когда базовое соединение завершило закрытие.

Вызов этого метода в конечном итоге приведет к закрытию соответствующего сокета, а также закроет связанный NetworkStream, который используется для отправки и получения данных, если они были созданы.

Ответ 3

Используйте слово: using. Хорошая привычка программировать.

using (TcpClient tcpClient = new TcpClient())
{
     //operations
     tcpClient.Close();
}

Ответ 4

Закрывает соединение сокета и позволяет повторно использовать сокет:

tcpClient.Client.Disconnect(false);

Ответ 5

За исключением некоторых внутренних протоколов, Close == Dispose.

Dispose вызывает tcpClient.Client.Shutdown(SocketShutdown.Both), но он ест любые ошибки. Возможно, если вы вызываете это напрямую, вы можете получить полезную информацию об исключении.

Ответ 6

Правильный способ закрыть сокет, чтобы вы могли повторно открыть:

tcpClient.Client.Disconnect(true);

Логический параметр указывает, хотите ли вы повторно использовать сокет:

Использование метода разъединения

Ответ 7

Несмотря на все соответствующие using операторы, вызывая Close, имея некоторые экспоненциальный отвали логики и воссоздания TcpClient я до сих пор был видеть проблемы, когда приложение не может восстановить соединение TCP без перезапуска приложения. Он продолжает терпеть неудачу с System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

Но есть опция LingerState на TcpClient которая кажется, что она, возможно, решила проблему (может не знать в течение нескольких месяцев, поскольку моя собственная аппаратная настройка только об этом часто не работает!). См. MSDN.

// This discards any pending data and Winsock resets the connection.
LingerOption lingerOption = new LingerOption(true, 0);

using (var tcpClient = new TcpClient 
       {SendTimeout = 2000, ReceiveTimeout = 2000, LingerState = lingerOption })
   ...

Ответ 8

Вы пробовали вызывать TcpClient.Dispose() явно?

И вы уверены, что у вас есть TcpClient.Close() и TcpClient.Dispose() - ed ВСЕ соединения?