..Прилегающее соединение было закрыто: при получении произошла непредвиденная ошибка
У меня есть следующий код:
private Uri currentUri;
private void Form1_Load(object sender, EventArgs e)
{
currentUri = new Uri(@"http://www.stackru.com");
HttpWebRequest myRequest = (HttpWebRequest) HttpWebRequest.Create("http://www.stackru.com");
WebProxy myProxy = new WebProxy("120.198.230.8:81");
myRequest.Proxy = myProxy;
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
webBrowser1.DocumentStream = myResponse.GetResponseStream();
webBrowser1.Navigating += new WebBrowserNavigatingEventHandler(webBrowser1_Navigating);
}
void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
if (e.Url.AbsolutePath != "blank")
{
currentUri = new Uri(currentUri, e.Url.AbsolutePath);
HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(currentUri);
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
webBrowser1.DocumentStream = myResponse.GetResponseStream();
e.Cancel = true;
}
}
после компиляции:
ошибка: необработанное исключение типа 'System.Net.WebException' произошло в System.dll
Дополнительная информация: базовое соединение было закрыто: при получении произошла непредвиденная ошибка.
на линии HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Помогите мне, пожалуйста
9 ответов
Основное соединение было закрыто: при получении произошла непредвиденная ошибка.
Эта проблема возникает, когда сервер или другое сетевое устройство неожиданно закрывает существующее соединение по протоколу управления передачей (TCP). Эта проблема может возникнуть, если значение тайм-аута на сервере или на сетевом устройстве слишком мало. Чтобы устранить эту проблему, см. Разрешения A, D, E, F и O. Проблема также может возникнуть, если сервер неожиданно сбрасывает соединение, например, если необработанное исключение приводит к сбою процесса сервера. Проанализируйте журналы сервера, чтобы увидеть, может ли это быть проблемой.
разрешение
Чтобы решить эту проблему, убедитесь, что вы используете самую последнюю версию.NET Framework.
Добавьте метод в класс, чтобы переопределить GetWebRequest
метод. Это изменение позволяет получить доступ к объекту HttpWebRequest. Если вы используете Microsoft Visual C#, новый метод должен быть похож на следующий.
class MyTestService:TestService.TestService
{
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest webRequest = (HttpWebRequest) base.GetWebRequest(uri);
//Setting KeepAlive to false
webRequest.KeepAlive = false;
return webRequest;
}
}
Настройка HttpWebRequest.KeepAlive
в false
не работал для меня
Поскольку я получал доступ к странице HTTPS, мне пришлось установить протокол безопасности точки обслуживания на Tls12.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Обратите внимание, что есть другие SecurityProtocolTypes
: SecurityProtocolType.Ssl3
, SecurityProtocolType.Tls
, SecurityProtocolType.Tls11
Так что, если Tls12 не работает для вас, попробуйте три оставшихся варианта.
Также обратите внимание, что вы можете установить несколько протоколов. Это предпочтительнее в большинстве случаев.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
- .NET 4.6 and above. You don’t need to do any additional work to support TLS 1.2, it’s supported by default.
.NET 4.5. TLS 1.2 is supported, but it’s not a default protocol. You need to opt-in to use it. The following code will make TLS 1.2 default, make sure to execute it before making a connection to secured resource:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
.NET 4.0. TLS 1.2 is not supported, but if you have.NET 4.5 (or above) installed on the system then you still can opt in for TLS 1.2 even if your application framework doesn’t support it. The only problem is that SecurityProtocolType in.NET 4.0 doesn’t have an entry for TLS1.2, so we’d have to use a numerical representation of this enum value:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
.NET 3.5 or below. TLS 1.2 is not supported. Upgrade your application to more recent version of the framework.
Мой хостинг-сервер блокирует запрос URL-адреса и кода сайта, получающего ту же ошибку
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
Потратив много времени, примените следующий шаг для решения этой проблемы
Добавлена строка перед URL-адресом вызова
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
все еще проблема не решена, я обновляю версию.NET до 4.7.2, но я думаю, что это необязательно
Последнее изменение. Я проверил уровень безопасности своего хостинг-сервера, который вызывает установление связи TLS для этого используемого сайта "https://www.ssllabs.com/ssltest/index.html",
а также проверяю, чтобы запросить уровень безопасности URL, тогда я обнаружил, что разница запрашиваемый URL-адрес должен включать набор шифров слабого уровня, который вы можете увидеть на изображении ниже
Теперь вот мой хостинг-сервер, поддерживающий Cipher Suites.
здесь вызывается, если у вас есть контроль над запрашиваемым сервером URL-адреса, тогда вы можете синхронизировать оба набора шифрования сервера. но в моем случае это невозможно, поэтому я применил следующий сценарий в Windows PowerShell на моем хост-сервере для включения требуемых наборов шифров слабого уровня.
Enable-TlsCipherSuite -Name "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"
Enable-TlsCipherSuite -Name "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
Enable-TlsCipherSuite -Name "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
Enable-TlsCipherSuite -Name "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
Enable-TlsCipherSuite -Name "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"
Enable-TlsCipherSuite -Name "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"
Enable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_GCM_SHA384"
Enable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_128_GCM_SHA256"
Enable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_CBC_SHA256"
Enable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_128_CBC_SHA256"
Enable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_CBC_SHA"
Enable-TlsCipherSuite -Name "TLS_RSA_WITH_AES_256_CBC_SHA"
после применения вышеупомянутого скрипта мой уровень Cipher Suite сервера хостинга выглядит как
Тогда моя проблема решилась.
Примечание. Понижение уровня безопасности сервера не рекомендуется.
Ни одно из решений не сработало для меня. В итоге я обнаружил следующую комбинацию:
- Клиентская система: Windows XP Pro SP3
- В клиентской системе установлен.NET Framework 2 SP1, 3, 3.5
- Программное обеспечение для.NET 2 с использованием классических веб-сервисов (.asmx)
- Сервер: IIS6
- Веб-сайт "Безопасные коммуникации" настроен на:
- Требуется безопасный канал
- Принять клиентские сертификаты
Видимо, именно этот последний вариант был причиной проблемы. Я обнаружил это, пытаясь открыть URL-адрес веб-службы непосредственно в Internet Explorer. Он просто зависал на неопределенный срок, пытаясь загрузить страницу. Отключение "Принимать сертификаты клиента" позволило странице загружаться нормально. Я не уверен, что это была проблема с этой конкретной системой (возможно, сбой сертификата клиента?), Так как я не использовал сертификаты клиента, эта опция работала для меня.
Я встретил то же исключение «Исключение при вызове « ExexeQuery» с аргументом (аргументами) «0»: «Базовое соединение было закрыто: при приеме произошла непредвиденная ошибка. "" с блоком сценария PowerShell`
#Setup Credentials to connect
$Username="user@domain.com"
$Password="pwd4user"
$securePassword = ConvertTo-SecureString $Password -AsPlainText -Force
#$Cred = Get-Credential
$Cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $securePassword)
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = $Cred
#Get the Library and Its Root Folder
$Library=$Ctx.web.Lists.GetByTitle($LibraryName)
$Ctx.Load($Library)
$Ctx.Load($Library.RootFolder)
$Ctx.ExecuteQuery()`
Приведенный выше блок кода может работать на одном из моих компьютеров, но на другом - нет, после того, как я добавил эту строку[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
в заголовке, но запустив его еще раз, я получил еще одно исключение «Исключение при вызове « ExexeQuery» с аргументами «0»: «Партнер возвратил неправильное имя для входа или ошибку пароля. Дополнительные сведения см. в разделе Сценарии обработки ошибок федерации. «» Я могу подтвердить, что с моими учетными данными все в порядке, потому что они могут работать на одном компьютере. затем я ищу информацию об исключении и получаю этот URL-адрес: партнер вернул неправильное имя для входа или ошибку пароля. Дополнительные сведения см. в разделе Сценарии обработки ошибок федерации.
сайт выяснил, что прокси-сервер может вызвать это исключение, затем я заметил, что прокси-серверы на этих двух компьютерах были разными, поэтому я сменил прокси-сервер на компьютере, и сценарий не работает. наконец, все исключения исчезли.
Перед выполнением запроса я поставил инструкцию, как показано ниже, и она устранила мою ошибку. Просто к вашему сведению, если это кому-то поможет.
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; ctx.ExecuteQuery();
Чтобы расширить ответ Барто Бернсманна, я хотел бы добавить, что можно получить универсальную, ориентированную на будущее реализацию за счет небольшого размышления:
static void AllowAllSecurityPrototols()
{ int i, n;
Array types;
SecurityProtocolType combined;
types = Enum.GetValues( typeof( SecurityProtocolType ) );
combined = ( SecurityProtocolType )types.GetValue( 0 );
n = types.Length;
for( i = 1; i < n; i += 1 )
{ combined |= ( SecurityProtocolType )types.GetValue( i ); }
ServicePointManager.SecurityProtocol = combined;
}
Я вызываю этот метод в статическом конструкторе класса, который обращается к Интернету.
Я также работал над проектом по очистке веб-страниц, и обнаружилась такая же проблема, применен приведенный ниже код, и он работал хорошо. Если вы не знаете о версиях TLS, вы можете применить все нижеприведенные, иначе вы можете применить конкретные.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;