Получение исключения EOF по вызову https

Мой код делает запрос https. Это мой код

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(UploadUrl);
            request.Method = "POST";
            request.KeepAlive = false;
            request.Credentials = new NetworkCredential(userid, testpwd);

            postData = "<root></root>";
            request.ContentType = "application/x-www-form-urlencoded";

            byte[] postDataBytes = Encoding.UTF8.GetBytes(postData);
            request.ContentLength = postDataBytes.Length;

            Stream requestStream = request.GetRequestStream();
            requestStream.Write(postDataBytes, 0, postDataBytes.Length);
            requestStream.Close();

            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                StreamReader responseReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                var result = responseReader.ReadToEnd();
                responseReader.Close();
                Console.WriteLine(result);
            }

Этот код работает хорошо, но внезапно бросает следующее исключение

System.Net.WebException

Сообщение об исключении: Подключенное соединение было закрыто: при отправке произошла непредвиденная ошибка.

Трассировка стека:  в System.Net.HttpWebRequest.GetRequestStream(TransportContext & контекст)  в System.Net.HttpWebRequest.GetRequestStream()  в CustomerProcessor.Delivery.Deliver(String content, Int32 productCategory, String identifier, String xsltFile)

Исключение имеет внутреннее исключение: Исключено: System.IO.IOException Сообщение об исключении: Получил неожиданный EOF или 0 байтов из транспортного потока.

Трассировка стека:  в System.Net.FixedSizeReader.ReadPacket(буфер Byte [], смещение Int32, количество Int32)  в System.Net.Security.SslState.StartReadFrame(буфер Byte [], Int32 readBytes, AsyncProtocolRequest asyncRequest)  в System.Net.Security.SslState.StartReceiveBlob(байт [] buffer, AsyncProtocolRequest asyncRequest)  в System.Net.Security.SslState.CheckCompletionBeforeNextReceive(сообщение ProtocolToken, asyncRequest AsyncProtocolRequest)  в System.Net.Security.SslState.StartSendBlob(Byte [] входящий, Int32-счет, AsyncProtocolRequest asyncRequest)  в System.Net.Security.SslState.ForceAuthentication(булевский буфер приемаFirst, Byte [], AsyncProtocolRequest asyncRequest)  в System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)  в System.Net.TlsStream.CallProcessAuthentication(состояние объекта)  в System.Threading.ExecutionContext.runTryCode(Object userData)  в System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(код TryCode, CleanoutCode CleanoutCode, Object userData)  в System.Threading.ExecutionContext.RunInternal(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта)  в System.Threading.ExecutionContext.Run(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта)  в System.Net.TlsStream.ProcessAuthentication(результат LazyAsyncResult)  в System.Net.TlsStream.Write(буфер Byte [], смещение Int32, размер Int32)  в System.Net.PooledStream.Write(буфер байта [], смещение Int32, размер Int32)  в System.Net.ConnectStream.WriteHeaders(логическое async)

Есть ли вероятность увидеть, что может быть причиной этой проблемы?

Ответ 1

Добавление этого вызова до запроса помогло мне:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

Итак, если вы используете https, попробуйте изменить стандартный SecurityProtocol по умолчанию.

Ответ 2

Другая потенциальная причина этого - если вы работаете в Windows Server 2003, она поддерживает только SSL 2.0, SSL 3.0, TLS 1.0. Все эти протоколы теперь рекомендуется отключать в свете последних эксплойтов, которые были найдены для этих протоколов, поэтому вы можете обнаружить, что с жесткого защищенного сервера с Windows Server 2003 невозможно подключиться, тогда как с вашего сервера будет хорошо разработка машина. В этом случае вы ничего не можете сделать, кроме как попросить команду администратора сервера назначения разрешить TLS1.0 или обновить ваш производственный сервер.

Источник поддержки SSL на Win2k3Server: http://blogs.msdn.com/b/kaushal/archive/2011/10/02/support-for-ssl-tls-protocols-on-windows.aspx

Ответ 3

Мой опыт - это как описано elRobbo. Мне нужно обновить сервер Win2k3 до Win2k8.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 

поддерживается только в .net 4.5, который не поддерживается в Win2k3...

Ответ 4

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

Это также имеет то преимущество, что:

using(Stream stm = req.GetRequestStream())
using(StreamWriter sw = new StreamWriter(stm))
{
  sw.Write(postData);
}

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

Ответ 5

Это сработало для меня:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Я создал эту строку перед созданием веб-запроса.