Не удалось прочитать данные из транспортного соединения: существующее соединение было принудительно закрыто удаленным хостом
У меня есть серверное приложение, и иногда, когда клиент пытается подключиться, я получаю следующую ошибку:
![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();
Что может быть причиной этой проблемы? Обратите внимание, что это не происходит все время
Ответы
Ответ 1
Эта ошибка обычно означает, что целевая машина запущена, но служба, к которой вы пытаетесь подключиться, недоступна. (Либо он остановился, разбился, либо занят другим запросом.)
На английском языке:
Соединение с машиной (удаленный хост/сервер/ПК, на котором выполняется служба), но поскольку служба не была доступна на, эта машина не знала, что делать с запросом.
Если соединение с устройством недоступно, вы увидите другую ошибку. Я забыл, что это такое, но он по строкам "Сервис недоступен" или "Недоступен".
Изменить - добавлено
Возможно, это связано с тем, что брандмауэр блокирует порт, но, учитывая, что вы говорите, что он прерывистый ( "иногда, когда клиент пытается подключиться" ), это очень маловероятно. Я не включал это изначально, потому что я решил это умственно, прежде чем отвечать.
Ответ 2
Я получил эту ошибку при вызове веб-сервиса. Эта проблема также была связана с безопасностью транспортного уровня. Я мог бы вызвать веб-сервис через проект веб-сайта, но при повторном использовании одного и того же кода в тестовом проекте я получил бы WebException, содержащее это сообщение. Добавив следующую строку перед тем, как решить проблему, выполните следующие действия:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
редактировать
System.Net.ServicePointManager.SecurityProtocol - это свойство выбирает версию протокола Secure Sockets Layer (SSL) или Transport Layer Security (TLS) для использования для новых подключений, использующих только схему Secure Hypertext Transfer Protocol (HTTPS); существующие соединения не изменяются.
Я считаю, что конфигурация SecurityProtocol
важна во время установления связи TLS при выборе версии протокола.
Согласование TLS - этот протокол используется для обмена всей информацией, необходимой обеим сторонам для обмена фактическими данными приложения с помощью TLS.
ClientHello - клиент отправляет сообщение ClientHello с указанием самой высокой версии протокола TLS, которую он поддерживает...
ServerHello - сервер отвечает сообщением ServerHello, содержащим выбранную версию протокола... Выбранная версия протокола должна быть самой высокой, как поддержка клиента, так и сервера. Например, если клиент поддерживает TLS версии 1.1, а сервер поддерживает версию 1.2, следует выбрать версию 1.1; версия 1.2 не должна быть выбрана.
Ответ 3
Моим конкретным сценарием было то, что у службы приложений Azure была минимальная версия TLS, измененная на 1.2
Я не знаю, был ли этот дефолт с этого момента, но его изменение в 1.0 заставило его работать.
Вы можете получить доступ к настройке внутри "Настройки SSL".
Ответ 4
Не уверен, какие исправления в этих блогах помогли, но один из них отсортировал эту проблему для меня...
http://briancaos.wordpress.com/2012/07/06/unable-to-read-data-from-the-transport-connection-the-connection-was-closed/
Трюк, который помог мне, заключался в том, чтобы отказаться от использования WebRequest и вместо этого использовать HttpWebRequest. HttpWebRequest позволяет мне играть с тремя важными настройками:
а также
http://briancaos.wordpress.com/2012/06/15/an-existing-connection-was-forcibly-closed-by-the-remote-host/
- ШАГ 1: отключить KeepAlive
- ШАГ 2: установите ProtocolVersion в Version10
- ШАГ 3: ограничение количества точек обслуживания
Ответ 5
Вызовы на HTTPS-сервисы с одного из наших серверов также бросали сообщение " Невозможно прочитать данные из транспортного соединения: существующее соединение было принудительно закрыто". Однако HTTP-сервис работал нормально. Использовал Wireshark, чтобы убедиться, что это был отказ от подтверждения TLS. Закончилось то, что набор шифров на сервере необходимо обновить.
Ответ 6
Это не поможет в периодических проблемах, но может быть полезно для других людей с аналогичной проблемой.
Я клонировал виртуальную машину и запустил ее в другой сети с новым IP-адресом, но не изменил привязки в IIS. Fiddler показывал мне "Невозможно прочитать данные из транспортного соединения: существующее соединение было принудительно закрыто удаленным хостом", и IE сказал мне "Включите TLS 1.0, TLS 1.1 и TLS 1.2 в дополнительных настройках". Изменение привязки к новому IP-адресу решило его для меня.
Ответ 7
По какой-то причине соединение с сервером было потеряно. Возможно, сервер явно закрыл соединение, или ошибка на сервере вызвала его неожиданное закрытие. Или что-то между клиентом и сервером (коммутатором или маршрутизатором) опустило соединение.
Это может быть код сервера, который вызвал проблему, и может быть и не так. Если у вас есть доступ к серверному коду, вы можете поместить некоторую отладочную информацию, чтобы сообщить вам, когда клиентские соединения закрыты. Это может дать вам некоторое представление о том, когда и почему соединения отбрасываются.
На клиенте вам необходимо написать свой код, чтобы учесть возможность сбоя сервера в любое время. Это так, как есть: сетевые соединения по своей сути ненадежны.
Ответ 8
Я получаю эту проблему в прошлом. Я использую 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!
}
Я думаю, что программа должна сначала прочитать связь, прежде чем что-либо делать, я не знаю, исправьте меня, если я ошибаюсь. Но, согласно моим исследованиям, это не проблема кода - это было фактически от самой машины.
Счастливое кодирование!
Ответ 9
Это решило мою проблему. Я добавил эту строку до того, как будет сделан запрос:
System.Net.ServicePointManager.Expect100Continue = false;
Казалось, что существует прокси-сервер на сервере, который не поддерживает поведение 100-continue.
Ответ 10
System.Net.ServicePointManager.Expect100Continue = false;
Эта проблема возникает из-за причины прокси-сервера, реализованного на веб-сервере. Чтобы обойти прокси-сервер, поместив эту строку перед вызовом службы отправки.
Ответ 11
У меня было приложение сторонней стороны (Fiddler), работающее, чтобы попытаться просмотреть отправленные запросы. Закрытие этого приложения исправило это для меня
Ответ 12
У нас была очень похожая проблема, когда клиентский веб-сайт пытался подключиться к нашей службе веб-API и получал то же сообщение. Это начало происходить совершенно неожиданно, когда не было никаких изменений кода или обновлений Windows на сервере, где работал IIS.
В нашем случае оказалось, что вызывающий веб-сайт использует версию .Net, которая поддерживает только TLS 1.0, и по какой-то причине сервер, на котором работает наш IIS, по-видимому, перестал принимать вызовы TLS 1.0. Чтобы диагностировать, что мы должны были явно включить TLS через реестр на сервере IIS, а затем перезапустить этот сервер. Это ключи reg:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.0\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.0\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.1\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.1\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001
If that doesn't do it, you could also experiment with adding the entry for SSL 2.0:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001
У моего ответа на другой вопрос здесь есть сценарий powershell, который мы использовали для добавления записей:
ПРИМЕЧАНИЕ. Включение старых протоколов безопасности не является хорошей идеей, в нашем случае правильным решением было заставить клиентский веб-сайт обновить свой код для использования TLS 1.2, но записи реестра, приведенные выше, могут помочь диагностировать проблему в первую очередь.
Ответ 13
Причина, по которой это происходило со мной, была в том, что у меня была рекурсивная зависимость в моем провайдере DI. В моем случае у меня было:
services.AddScoped(provider => new CfDbContext(builder.Options));
services.AddScoped(provider => provider.GetService<CfDbContext>());
Исправлено было просто удалить вторую сферу обслуживания регистрации
services.AddScoped(provider => new CfDbContext(builder.Options));
Ответ 14
Если у вас есть сертификат https для домена, убедитесь, что у вас есть привязка https к имени домена в IIS.
В IIS → Выберите домен → Нажмите на привязки
Откроется окно привязок сайта. Добавьте привязку для https.
Ответ 15
Возникла похожая проблема, и возникали следующие ошибки в зависимости от того, какое приложение я использовал, и если мы обошли брандмауэр/балансировщик нагрузки или нет:
HTTPS рукопожатие [бла] (для # 136) не удалось. System.IO.IOException Невозможно прочитать данные из транспорта соединение: существующее соединение было принудительно закрыто удаленным хозяйничать
и
Ошибка ReadResponse(): сервер не вернул полный ответ на этот запрос. Сервер вернул 0 байт.
Проблема оказалась в том, что сертификат сервера SSL был пропущен и не был установлен на нескольких серверах.
Ответ 16
Попробуйте проверить, если вы можете установить рукопожатие в первую очередь. У меня была эта проблема раньше при загрузке файла, и я только выяснил, что проблема была в несуществующем маршруте, когда я удалил загрузку и проверил, может ли он войти в систему, учитывая параметры.