Невозможно прочитать данные из транспортного соединения: существующее соединение было принудительно закрыто удаленным хостом - PullRequest
78 голосов
/ 24 марта 2011

У меня есть серверное приложение, и иногда, когда клиент пытается подключиться, я получаю следующую ошибку:

enter image description here

ПРИМЕЧАНИЕ: «Не удалось получить поток от клиента или не удалось войти в систему» ​​- это текст, добавленный мной в оператор catch

и строка, на которой он останавливается (sThread: строка 96):

tcpClient = (TcpClient)client;
clientStream = tcpClient.GetStream();
sr = new StreamReader(clientStream);
sw = new StreamWriter(clientStream);

// line 96:                 
a = sr.ReadLine();

Что может быть причиной этой проблемы? Обратите внимание, что это не происходит постоянно

Ответы [ 15 ]

131 голосов
/ 11 марта 2017

Я получил эту ошибку при звонке в веб-сервис. Эта проблема также была связана с безопасностью на транспортном уровне. Я мог бы вызвать веб-сервис через проект веб-сайта, но при повторном использовании того же кода в тестовом проекте я получил бы исключение WebException, содержащее это сообщение. Добавление следующей строки перед выполнением вызова решило проблему:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Редактировать

System.Net.ServicePointManager.SecurityProtocol - Это свойство выбирает версию Secure Sockets Layer (SSL) или транспорта Протокол уровня безопасности (TLS) для использования в новых соединениях, использующих Только схема защищенного протокола передачи гипертекста (HTTPS); существующий соединения не изменены.

Я считаю, что конфигурация SecurityProtocol важна во время рукопожатия TLS при выборе версии протокола.

TLS handshake - Этот протокол используется для обмена всей информацией, необходимой обеим сторонам для обмена фактическими данными приложения по TLS.

ClientHello - Клиент отправляет сообщение ClientHello, указывающее самую высокую версию протокола TLS, которую он поддерживает ...

ServerHello - Сервер отвечает сообщением ServerHello, содержащим выбранную версию протокола ... Выбранная версия протокола должна быть самой высокой, которую поддерживают и клиент, и сервер. Например, если клиент поддерживает TLS версии 1.1, а сервер поддерживает версию 1.2, следует выбрать версию 1.1; Версия 1.2 не должна быть выбрана.

48 голосов
/ 24 марта 2011

Эта ошибка обычно означает, что целевой компьютер работает, но служба, к которой вы пытаетесь подключиться, недоступна.(Либо он остановился, либо вышел из строя, либо занят другим запросом.)

На английском языке: установлено соединение с машиной (удаленный хост / сервер / ПК, на котором работает служба)но поскольку служба была недоступна на этой машине, машина не знала, что делать с запросом.

Если подключение к машине было недоступно, вы увидитедругая ошибка.Я забыл, что это такое, но это похоже на «Служба недоступна» или «Недоступен».

Изменить - добавлено

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

26 голосов
/ 14 июля 2018

В моем конкретном случае сценарий службы Azure изменил минимальную версию TLS на 1.2

.

Я не знаю, будет ли это по умолчанию с этого момента, но изменение его на 1.0 заставило его работать.

Вы можете получить доступ к настройке внутри «Настройки SSL».

15 голосов
/ 02 июля 2013

Не уверен, какие из исправлений в этих постах блога помогли, но один из них решил эту проблему для меня ...

http://briancaos.wordpress.com/2012/07/06/unable-to-read-data-from-the-transport-connection-the-connection-was-closed/

Хитрость, которая помогла мне, заключалась в том, чтобы выйти из WebRequest и использовать вместо него HttpWebRequest. HttpWebRequest позволяет мне играть с 3 важными настройками:

и

http://briancaos.wordpress.com/2012/06/15/an-existing-connection-was-forcibly-closed-by-the-remote-host/

  • ШАГ 1: Отключить KeepAlive
  • ШАГ 2: Установите ProtocolVersion на Version10
  • ШАГ 3: Ограничение количества точек обслуживания
10 голосов
/ 02 октября 2015

При вызовах служб HTTPS с одного из наших серверов также выдавалось исключение « Невозможно прочитать данные из транспортного соединения: существующее соединение было принудительно закрыто ». HTTP-сервис работал нормально. Использовал Wireshark, чтобы увидеть, что это был сбой TLS. Закончилось тем, что комплект шифров на сервере нужно было обновить.

4 голосов
/ 23 марта 2016

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

Я клонировал виртуальную машину и запустил ее в другой сети с новым IP-адресом, но не изменил привязки в IIS. Fiddler показывал мне «Невозможно прочитать данные из транспортного соединения: существующее соединение было принудительно закрыто удаленным хостом», а IE говорил мне «Включите TLS 1.0, TLS 1.1 и TLS 1.2 в дополнительных настройках». Изменение привязки к новому IP-адресу решило это для меня.

2 голосов
/ 04 марта 2018

Это решило мою проблему. Я добавил эту строку перед выполнением запроса:

System.Net.ServicePointManager.Expect100Continue = false;

Кажется, на пути к серверу есть прокси, который не поддерживает 100-продолжение.

2 голосов
/ 23 марта 2017

Я получил эту проблему в прошлом. Я использую PostgreSQL , и когда я запускаю свою программу, иногда она подключается, а иногда выдает такую ​​ошибку.

Когда я экспериментирую с моим кодом, я помещаю код подключения в самую первую строку под общедоступной формой. Вот пример:

ДО:

    public Form1()
        {
        //HERE LIES SOME CODES FOR RESIZING MY CONTROLS DURING RUNTIME
        //CODE
        //CODE AGAIN
        //ANOTHER CODE
        //CODE NA NAMAN
        //CODE PA RIN!





        //Connect to Database to generate auto number
        NpgsqlConnection iConnect = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Password=pass;Database=DB");
        iConnect.Open();
        NpgsqlCommand iQuery = new NpgsqlCommand("Select * from table1", iConnect);
        NpgsqlDataReader iRead = iQuery.ExecuteReader();
        NpgsqlDataAdapter iAdapter = new NpgsqlDataAdapter(iQuery);

        DataSet iDataSet = new DataSet();
        iAdapter.Fill(iDataSet, "ID");

        MessageBox.Show(iDataSet.Tables["ID"].Rows.Count.ToString());
        }

ТЕПЕРЬ:

    public Form1()
        {
        //Connect to Database to generate auto number
        NpgsqlConnection iConnect = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Password=pass;Database=DB");
        iConnect.Open();
        NpgsqlCommand iQuery = new NpgsqlCommand("Select * from table1", iConnect);
        NpgsqlDataReader iRead = iQuery.ExecuteReader();
        NpgsqlDataAdapter iAdapter = new NpgsqlDataAdapter(iQuery);

        DataSet iDataSet = new DataSet();
        iAdapter.Fill(iDataSet, "ID");

        MessageBox.Show(iDataSet.Tables["ID"].Rows.Count.ToString());





        //HERE LIES SOME CODES FOR RESIZING MY CONTROLS DURING RUNTIME
        //CODE
        //CODE AGAIN
        //ANOTHER CODE
        //CODE NA NAMAN
        //CODE PA RIN!

        }

Я думаю, что программа должна сначала прочитать соединение, прежде чем что-то делать, не знаю, поправьте меня, если я ошибаюсь. Но, согласно моим исследованиям, это не проблема кода - на самом деле это была сама машина.

Счастливого кодирования!

2 голосов
/ 24 марта 2011

По какой-то причине соединение с сервером было потеряно. Возможно, сервер явно закрыл соединение, или ошибка на сервере привела к его неожиданному закрытию. Или что-то между клиентом и сервером (коммутатором или маршрутизатором) разорвало соединение.

Это может быть серверный код, вызвавший проблему, а может и не быть. Если у вас есть доступ к коду сервера, вы можете добавить туда отладку, чтобы сообщить, когда клиентские соединения закрыты. Это может дать вам некоторое представление о том, когда и почему прерывается соединение.

На клиенте вы должны написать свой код, чтобы учесть возможность сбоя сервера в любое время. Так оно и есть: сетевые соединения по своей природе ненадежны.

1 голос
/ 29 мая 2018
System.Net.ServicePointManager.Expect100Continue = false;

Эта проблема иногда возникает из-за того, что прокси-сервер реализован на веб-сервере.Чтобы обойти прокси-сервер, поставив эту строку перед вызовом службы отправки.

...