通过 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 异常的主要内容,如果未能解决你的问题,请参考以下文章