底层连接已关闭——API 端点调用失败
Posted
技术标签:
【中文标题】底层连接已关闭——API 端点调用失败【英文标题】:The underlying connection was closed -- API endpoint call fails 【发布时间】:2016-11-30 16:20:27 【问题描述】:我正在尝试确定当我使用 HTTPS 而不是来自 Windows Server 2012 R2 的 HTTP 时,对 Restful API 端点的调用失败的原因。当我在笔记本电脑(Windows 7)上本地运行应用程序时,同样的 HTTPS 调用有效。
不幸的是,我无法让 Fiddler 显示从 Web 服务器上的应用程序对 API 的调用。 AppContainer Loopback Exemption Utility 尝试枚举 AppContainers 列表时出错。 服务器也被组策略锁定,因此我无法关闭防火墙来尝试解决 Fiddler 问题。
对 API 的调用是:
public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request)
client = new HttpClient();
// removed code for setting ignoreCertErrors and environmentName
if (ignoreCertErrors && environmentName.ToUpper() != "PROD")
ServicePointManager.ServerCertificateValidationCallback = delegate return true; ;
return client.SendAsync(request);
收到的错误:
================================================ =================== 消息:底层连接已关闭:意外错误 发送时发生。堆栈跟踪: 在 System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) 在 System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResultar)
================================================ =================== 消息:无法从传输连接读取数据:一个 现有连接被远程主机强行关闭。堆 追踪: 在 System.Net.TlsStream.EndWrite(IAsyncResult asyncResult) 在 System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
================================================ =================== 消息:远程主机强制关闭现有连接 堆栈跟踪: 在 System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult) 在 System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
================================================ ===================
如何获得更多细节?我试图避免使用 Wireshark 等低级工具,我希望有选项跟踪/记录/捕获有关应用程序调用失败的 API 的更多详细信息。
更新 - 这是失败时的跟踪信息:
System.Net 信息:0 : [2292] SecureChannel#49584532::.ctor(hostname=XX.XX.com, clientCertificates=0, encryptionPolicy=RequireEncryption)
System.Net 信息:0 : [2292] SecureChannel#49584532 - 剩下 0 个客户端 证书可供选择。
System.Net 信息:0:[2292] 使用 缓存的凭据句柄。 System.Net 信息:0:[2292] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = (null), targetName = XX.XX.com, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation) System.Net 信息: 0: [2292] InitializeSecurityContext(In-缓冲区长度=0,输出缓冲区长度=178,返回代码=ContinueNeeded)。
System.Net.Sockets 详细:0:[2292] Socket#14347911::BeginSend()
System.Net.Sockets 详细:0:[2292] 退出 Socket#14347911::BeginSend() -> OverlappedAsyncResult#19699911 System.Net.Sockets 详细:0:[2292] 来自 Socket#14347911::PostCompletion 的数据
[删除]
System.Net.Sockets 详细:0:[2292] 套接字#14347911::EndSend(OverlappedAsyncResult#19699911)
System.Net.Sockets 详细:0:[2292] 退出 Socket#14347911::EndSend() -> Int32#178
System.Net.Sockets 详细:0:[2292] Socket#14347911::BeginReceive()
System.Net.Sockets Verbose: 0 : [2292] Exiting Socket#14347911::BeginReceive() -> OverlappedAsyncResult#2389992
System.Net.Sockets 详细:0:[2292] 套接字#14347911::EndReceive(OverlappedAsyncResult#2389992)
System.Net.Sockets 错误:0:[2292] Socket#14347911::UpdateStatusAfterSocketError() - ConnectionReset
System.Net.Sockets 错误:0:[2292] 中的异常 Socket#14347911::EndReceive - 强制现有连接 被远程主机关闭。 System.Net.Sockets 详细:0:[2292] 退出 Socket#14347911::EndReceive() -> Int32#0
System.Net.Sockets 详细:0:[2292] Socket#14
【问题讨论】:
对 api 的调用可能失败。当您连接到服务器时,您正在使用来宾权限运行,这些权限通常没有在服务器上运行 api 的凭据。该 api 必须安装在服务器上才能以管理员权限运行。为了验证我是否正确,我会检查服务器上的事件查看器以获取有关错误的更多详细信息。 使用 HTTP 对 API 的相同调用有效,但是当我使用 HTTPS 切换 API URI 时,它会引发上述错误。 您是否测试空响应?不确定根本原因,但我怀疑您可能会收到空包。 这是对 API 端点的完全相同的调用,HTTP 工作但 HTTPS 从服务器失败。 HTTPS API 调用在本地使用相同的代码工作。不确定如何处理空值会是一个问题。 【参考方案1】:日志条目:
System.Net.Sockets 错误:0:[2292] Socket#14347911::UpdateStatusAfterSocketError() - ConnectionReset
是由阻止端口的防火墙引起的。添加新的防火墙规则后,问题就解决了。
【讨论】:
以上是关于底层连接已关闭——API 端点调用失败的主要内容,如果未能解决你的问题,请参考以下文章