通过 https 调用获取 EOF 异常

Posted

技术标签:

【中文标题】通过 https 调用获取 EOF 异常【英文标题】:Getting EOF exception over https call 【发布时间】: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(布尔异步)

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

【问题讨论】:

【参考方案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;

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

【讨论】:

我不得不使用这里的解决方案来让 Tls12 工作:community.developer.authorize.net/t5/Integration-and-Testing/…【参考方案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之类的东西,可以设置为直接写入有问题的流。

【讨论】:

以上是关于通过 https 调用获取 EOF 异常的主要内容,如果未能解决你的问题,请参考以下文章

readObject 的 EOF 异常

(保姆式教程:从下数据到画图)python如何利用EOF分析SSTA海温异常现象并画图

为啥使用 readUTF 阅读时出现 EOF 异常?

关于获取java异常的方法

解析异常 EOF Hive

Go websocket错误:关闭1006(异常关闭):意外EOF