底层连接已关闭——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 端点调用失败的主要内容,如果未能解决你的问题,请参考以下文章

Authorize.net : 底层连接已关闭

SSIS 基础连接已关闭:发送时发生意外错误

调用 SOAP 时,“底层连接已关闭:预期保持活动状态的连接已被服务器关闭”

WebException:底层连接已关闭

自签名证书。底层连接已关闭:无法建立信任关系

如何在向某些站点发出 HttpWebRequest 时修复“底层连接已关闭:连接已意外关闭”