.NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决

简介: .NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决

前言:

  前段时间在对接第三方接口的时候发生了一个非常奇葩的问题,就是使用 .NET Framework 4.6 HttpWebRequest进行网络请求的相关问题。背景,关于调用第三方的接口都是使用使用自己封装的一个HttpWebRequestHepler帮助类,在本地开发时调用第三方接口都是正常的。然而当我部署到运维给我一个服务器(阿里云服务器)时刚开始提示是请求被中止: 未能创建 SSL/TLS 安全通道,之后经过一番修改以后就是提示基础连接已经关闭: 发送时发生错误。之后尝试了各种方法,还是没有办法解决基础连接已经关闭: 发送时发生错误这个问题。最后真的是无能为力,光这个问题找了一下午的解决方案,最后换到了我自己的阿里云服务器是可以正常调通第三方接口的。然后让运维看了下服务器结果是这个服务器都没有开通外网,所以导致了这个问题的出现。下面记录下问题排除的过程,希望能够帮助到遇到这种坑的小伙伴。

一、自己封装的一个通用的HttpWebRequestHepler Http Web网络请求帮助类:

/// <summary>
    /// Http Web网络请求帮助类
    /// </summary>
    public class HttpWebRequestHepler
    {
        private static HttpWebRequestHepler _httpWebRequestHepler;
        private string _resContent;//响应内容
        private string _errInfo;//错误信息
        private int _responseCode;//响应状态码
        public static HttpWebRequestHepler _
        {
            get => _httpWebRequestHepler ?? (_httpWebRequestHepler = new HttpWebRequestHepler());
            set => _httpWebRequestHepler = value;
        }
        /// <summary>
        /// 数据请求
        /// </summary>
        /// <param name="requestUrl">请求地址</param>
        /// <param name="postData">请求参数</param>
        /// <param name="accessToken">授权token</param>
        /// <param name="contentType">请求标头值类型</param>
        /// <param name="method">请求方式</param>
        /// <returns></returns>
        public string HttpWebResponseData(string requestUrl, string postData, string accessToken = "", string contentType = "application/json", string method = "POST")
        {
            HttpWebResponse wr = null;
            try
            {
                var hp = (HttpWebRequest)WebRequest.Create(requestUrl);
                hp.Timeout = 60 * 1000 * 10;//以毫秒为单位,设置等待超时10分钟
                hp.Method = method;
                hp.ContentType = contentType;
                if (!string.IsNullOrWhiteSpace(accessToken))
                {
                    hp.Headers.Add("Authorization", "Bearer " + accessToken);//增加headers请求头信息
                }
                if (postData != "")//带参数请求
                {
                    byte[] data = Encoding.UTF8.GetBytes(postData);
                    hp.ContentLength = data.Length;
                    Stream ws = hp.GetRequestStream();
                    // 发送数据
                    ws.Write(data, 0, data.Length);
                    ws.Close();
                }
                wr = (HttpWebResponse)hp.GetResponse();
                var sr = new StreamReader(wr.GetResponseStream() ?? throw new InvalidOperationException(), Encoding.UTF8);
                this._resContent = sr.ReadToEnd();
                sr.Close();
                wr.Close();
            }
            catch (Exception exp)
            {
                this._errInfo += exp.Message;
                if (wr != null)
                {
                    this._responseCode = Convert.ToInt32(wr.StatusCode);
                }
                return this._resContent;
            }
            this._responseCode = Convert.ToInt32(wr.StatusCode);
            return this._resContent;
        }
    }

二、请求被中止: 未能创建 SSL/TLS 安全通道问题解决:

  把项目部署到阿里云服务器中,请求第三方提示请求被中止: 未能创建 SSL/TLS 安全通道。首先字面上可以看出来这个https请求安全协议的问题。微软官方说明是,NET 4.6需要添加

ServicePointManager.SecurityProtocol属性,指定schnanel安全包支持的安全协议

微软官方解释:

此属性选择要用于新连接的安全套接字层 (SSL) 或传输层安全性 (TLS) 协议的版本;不会更改现有连接。

从 .NET Framework 4.7 开始,此属性的默认值为 SecurityProtocolType.SystemDefault这允许基于 SslStream ((如 FTP、HTTP 和 SMTP) )的 .NET Framework 网络 api 从操作系统或系统管理员执行的任何自定义配置继承默认安全协议。 有关默认情况下在每个版本的 Windows 操作系统上启用了哪些 SSL/TLS 协议的信息,请参阅 TLS/SSL (SCHANNEL SSP) 中的协议

对于通过 .NET Framework 4.6.2 的 .NET Framework 版本,不会列出此属性的默认值。 安全环境不断变化,默认的协议和保护级别会随着时间的推移而更改,以避免已知的漏洞。 默认值因单独的计算机配置、已安装的软件和应用的修补程序而异。

解决方案:

//todo:指定请求包的安全协议,因为不知道你当前项目到底是哪个版本所以为了安全保障都加上
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.SystemDefault | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;

1336199-20210417184745341-146613190.png

三、基础连接已经关闭: 发送时发生错误

       这个问题查阅了网上几个比较典型的博客试了下,结果都没有办法解决我的问题,一下记录下这几个博客的解决方案,希望可以帮助到遇到这样问题的小伙伴。

1、一般来说添加了上面的ServicePointManager.SecurityProtocol属性就可以解决这个基础连接关闭的问题。

2、C# HttpRequest基础连接已经关闭: 接收时发生意外错误(原文地址):

//增加下面两个属性即可
hp.KeepAlive = false;
hp.ProtocolVersion = HttpVersion.Version10;

四、开启阿里云服务器外网(我的解决方案)

  查看一下你的服务器是否开通了外网,假如没有开通服务器外网在进行尝试。阿里云服务器配置外网访问参考。因为这个奇葩问题花费了一天宝贵的时间,考虑问题还是得多方面考虑。

相关实践学习
通义万相文本绘图与人像美化
本解决方案展示了如何利用自研的通义万相AIGC技术在Web服务中实现先进的图像生成。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情:&nbsp;https://www.aliyun.com/product/ecs
相关文章
|
运维 安全 网络安全
.NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决
.NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决
1872 0
.NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决
|
6月前
|
存储 JavaScript 前端开发
如何高效实现 vue 文件批量下载及相关操作技巧
在Vue项目中,实现文件批量下载是常见需求。例如文档管理系统或图片库应用中,用户可能需要一次性下载多个文件。本文介绍了三种技术方案:1) 使用`file-saver`和`jszip`插件在前端打包文件为ZIP并下载;2) 借助后端接口完成文件压缩与传输;3) 使用`StreamSaver`解决大文件下载问题。同时,通过在线教育平台的实例详细说明了前后端的具体实现步骤,帮助开发者根据项目需求选择合适方案。
533 0
|
Oracle Java 关系型数据库
入职必会-开发环境搭建41-Linux软件安装-安装JDK
本文介绍了在Linux系统中下载和安装JDK
531 3
入职必会-开发环境搭建41-Linux软件安装-安装JDK
|
数据采集 JSON API
.NET 3.5 中 HttpWebRequest 的核心用法及应用
【9月更文挑战第7天】在.NET 3.5环境下,HttpWebRequest 类是处理HTTP请求的一个核心组件,它封装了HTTP协议的细节,使得开发者可以方便地发送HTTP请求并接收响应。本文将详细介绍HttpWebRequest的核心用法及其实战应用。
671 6
|
Rust 安全 前端开发
30天拿下Rust之图形编程
30天拿下Rust之图形编程
324 0
|
负载均衡 NoSQL Java
聊聊 分布式 WebSocket 集群解决方案(一)
聊聊 分布式 WebSocket 集群解决方案
聊聊 分布式 WebSocket 集群解决方案(一)
|
安全
HTTP请求错误:”基础连接已关闭,发送时发生错误”
本文讲解HTTP请求错误:”基础连接已关闭,发送时发生错误”的解决方法。
605 0
|
传感器 监控 数据可视化
万界星空MES安灯管理:优化生产监控的重要工具
MES安灯管理是一种基于物理安灯和数字化管理的生产异常管理工具。它通过物理安灯和数字化系统的结合,实现对生产异常的实时监控和及时反馈,从而帮助企业快速响应和解决生产异常,提高生产效率和产品质量。
403 0
万界星空MES安灯管理:优化生产监控的重要工具
报错信息 "ResultCode:403"
报错信息 "ResultCode:403"
925 3