【问题标题】:Getting EOF exception over https call通过 https 调用获取 EOF 异常
【发布时间】:2011-07-19 22:43:23
【问题描述】:

我的代码发出 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(字符串内容,Int32 productCategory,字符串标识符,字符串 xsltFile)

异常有一个内部异常:发生异常: System.IO.IOException 异常消息是:Received an unexpected 传输流中的 EOF 或 0 个字节。

堆栈跟踪:在 System.Net.FixedSizeReader.ReadPacket(Byte[] 缓冲区,Int32 偏移量,Int32 计数)在 System.Net.Security.SslState.StartReadFrame(字节 [] 缓冲区,Int32 readBytes,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartReceiveBlob(字节 [] 缓冲区, AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.CheckCompletionBeforeNextReceive(协议令牌 消息,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.StartSendBlob(字节 [] 传入,Int32 计数,AsyncProtocolRequest asyncRequest)在 System.Net.Security.SslState.ForceAuthentication(布尔接收第一, Byte[] 缓冲区,AsyncProtocolRequest asyncRequest) 在 System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult 懒惰的结果)在 System.Net.TlsStream.CallProcessAuthentication(对象状态)在 System.Threading.ExecutionContext.runTryCode(对象用户数据)在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode 代码,CleanupCode backoutCode,对象 userData)在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext、ContextCallback 回调、对象状态)在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback 回调、对象状态)在 System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult 结果)
在 System.Net.TlsStream.Write(字节 [] 缓冲区,Int32 偏移量,Int32 大小) 在 System.Net.PooledStream.Write(Byte[] 缓冲区,Int32 偏移量,Int32 大小)在 System.Net.ConnectStream.WriteHeaders(布尔异步)

是否有机会查看导致此问题的原因?

【问题讨论】:

    标签: .net http


    【解决方案1】:

    在请求之前添加此调用对我有帮助:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
    

    因此,如果您使用 https,请尝试更改默认的 SecurityProtocol。

    【讨论】:

    • 这救了我的命.. 显然仍有网站在 SSL2.0 上运行。
    • 不适合我。我的设置是这样但没有帮助: System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | System.Net.SecurityProtocolType.Tls | (SecurityProtocolType)768/*TLS1.1*/ | (SecurityProtocolType)3072/*TLS1.2*/;
    • 也许你可以试试这个:ServicePointManager.SecurityProtocol |= SecurityProtocolType.Ssl3|安全协议类型.Tls|安全协议类型.Tls11 | SecurityProtocolType.Tls12;
    【解决方案2】:

    另一个可能的原因 - 如果您在 Windows Server 2003 上运行,它仅支持 SSL 2.0、SSL 3.0、TLS 1.0。鉴于最近发现这些协议的漏洞,现在建议禁用所有这些协议,因此您可能会发现无法从 Windows Server 2003 连接到严格安全的服务器,而从您的开发机器。除了要求目标服务器管理员团队允许 TLS1.0 或升级您的生产服务器之外,您实际上无能为力。

    Win2k3Server 上的 SSL 支持来源:http://blogs.msdn.com/b/kaushal/archive/2011/10/02/support-for-ssl-tls-protocols-on-windows.aspx

    【讨论】:

    • 您先生是个天才,我欠您一杯啤酒。谢谢!
    • 你买过那种啤酒吗?
    【解决方案3】:

    这对我有用:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    

    我在创建网络请求之前已经写了那行。

    【讨论】:

    【解决方案4】:

    我的经验和 elRobbo 描述的一样。我必须将 Win2k3 服务器升级到 Win2k8。

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 
    

    仅.net 4.5 支持,Win2k3 不支持...

    【讨论】:

      【解决方案5】:

      我不知道为什么(特别是因为它违背了我在这件事上看到的文档),但我发现忽略了 RequestLength 的分配。而是直接写入请求流而不设置标头。

      这还有一个好处:

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

      在我看来更简单,并且在数据较大且逐个写入的情况下具有更大的优势,或者来自XMLWriter之类的东西,可以设置为直接写入有问题的流。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-20
        • 2016-06-11
        • 2018-04-05
        • 2012-05-07
        • 2018-08-02
        相关资源
        最近更新 更多