首页 > 编程语言 >C# 采用HttpWebRequest 、WebClient和HttpClient下载https的文件异常问题

C# 采用HttpWebRequest 、WebClient和HttpClient下载https的文件异常问题

时间:2024-02-22 17:55:07浏览次数:33  
标签:C# ServicePointManager 提示 https HttpWebRequest WebClient HttpClient

今天有个客户反应,程序下载文件失败,无法正常使用。

远程客户电脑后,查看错误日志,都是提示https:****************************.dll等一系列文件的下载错误提示

提示基础连接已经关闭: 发送时发生错误。

在网上找了很多方案都没有能解决,大多都是https链接时增加指定协议,很遗憾未能解决

        HttpWebRequest request;
            HttpWebResponse response;
            request = (HttpWebRequest)WebRequest.Create(strUrl);
            if (isHttps)
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                request.ProtocolVersion = HttpVersion.Version10;

                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            }

找不到原因,客户又着急使用,就想着换成WebClient下载类试试,于是写了个粗糙的demo

WebClient webClient = new WebClient();
webClient.DownloadFile(textBox1.Text, Path.GetFileName(textBox1.Text));

发现还是提示同样的错误,这个时候一头雾水,心里万马奔腾

心思不能乱,不行我在换,72般武艺都耍上,于是用HttpClient类,写个demo试试

 using (HttpClient client = new HttpClient())
 {
     // 使用异步方法下载文件
     HttpResponseMessage response = await client.GetAsync(textBox1.Text);
     response.EnsureSuccessStatusCode(); // 确保请求成功

     // 保存文件
     using (FileStream fileStream = File.Create( Path.GetFileName(textBox1.Text)))
     {
         await response.Content.CopyToAsync(fileStream);
     }
 }

发现还是不能下载文件,但是错误提示有变化,提示为“因为算法不同,客户端与服务器无法通信”

于是寻找这个错误的解决方案,需要在注册表这个位置将协议值修改下

计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols

 一看客户电脑上,好几个,一个个修改太麻烦,直接将协议改名,让这个设置失效。

在启动测试程序下载文件,发现正常了,完工。

 

后来在网上又发现一个解决方案,感觉可能能行,由于客户问题处理完后,无法在霸占其电脑了,将这个方案记录下,后续遇到在验证,或者有遇到相同问题的天涯沦落人验证后给我留言,谢谢

在工作中要获取一个网络api下的内容,因为要auth认证,本以为很简单

string url="https://.....";
string usernamePassword = CustomerID + ":" + CustomerCertificate;
string basic = Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword));
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
myReq.Headers.Add("Authorization", "Basic " + basic);
HttpWebResponse myRes = (HttpWebResponse)myReq.GetResponse();  //<-- 这里就报错了
Stream resStream = myRes.GetResponseStream();
StreamReader strReader = new StreamReader(resStream);
string resStr = strReader.ReadToEnd();
Console.WriteLine(resStr);

 

结果运行时提示“提示基础连接已经关闭: 发送时发生错误。”
在浏览器下访问网址则正常,刚开始怀疑是basic不对,在浏览器下用同样的值模拟了一下能正常获取,然后把https换成http程序又能正常获取了,定位到问题出在ssl证书上
查了一下资料
添加以下代码

ServicePointManager.Expect100Continue = true;
ServicePointManager.CheckCertificateRevocationList = true;
ServicePointManager.DefaultConnectionLimit = 100;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; 
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

 

改回https还是提示原来的异常,换了另外一个https的网址测试却又正常,在浏览器下对比两个https网址的ssl证书,发现能正常访问的测试网址是tls1.0 不能访问的网址是tls1.2
找到问题了,原来在.net4.5以下tls1.2的设置如下

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; 
//.net4.5及以上
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

再次运行,ok

 

标签:C#,ServicePointManager,提示,https,HttpWebRequest,WebClient,HttpClient
From: https://www.cnblogs.com/ankeyliu/p/18027866

相关文章

  • Codeforces 1876F - Indefinite Clownfish
    首先注意到这样一个性质:既然两个序列的平均值相同,并且又形成公差\(\pm1\)的等差数列,就必然会存在一个元素\(x\)满足\(x\)在两个序列中都出现过(否则两个序列的值域区间不交,值域区间靠后的那个显然平均值比靠前的那个大)。那么我们枚举\(x\)在两个序列中出现的位置\(p\)和......
  • Codeforces Round 923 (Div. 3)
    A.MakeitWhite#include<bits/stdc++.h>usingnamespacestd;usingi32=int32_t;usingi64=longlong;usingi128=__int128;usingldb=longdouble;#defineinti64usingvi=vector<int>;usingpii=pair<int,int>;usingvii......
  • 解决mac下 php 提示dyld: Library not loaded: /opt/homebrew/opt/icu4c/lib/icui18n.
    产生原因是使用brewupdate后icu4c更新到了最新的版本导致php依赖的版本不一致,进入到/opt/homebrew/opt/icu4c/lib目录下查看没有icui18n.69.dylib文件 解决方法:网上下载icu4c69版本重新编译安装下载地址:https://github.com/unicode-org/icu/releases/tag/release-69-1只需......
  • <kubernetes_sd_config>
    -source_labels:[__meta_kubernetes_service_annotation_prometheus_io_path]action:replacetarget_label:__metrics_path__regex:(.+) 您提供的配置片段是一个Prometheus的relabeling规则。Prometheus使用relabeling来动态地修改......
  • 博客C
    《系统科学方法概论》第三章——信息方法《系统科学方法概论》第三章详细探讨了信息方法的重要性及其在系统工程中的应用。阅读后,我对信息方法有了更深入的认识。信息方法是基于信息科学的原理和方法,用于处理和解决问题的一种系统性思维方式。在信息时代,信息的获取、处理和应用......
  • Docker Swarm部署nginx+api-service实现负载均衡
    背景介绍api服务开发完毕之后如何快速部署实现负载均衡。如果不是重量级的项目,非常建议使用DockerSwarm来实现,非常简单高效且稳定。关于DockerSwarm集群的构建详见我的另一篇博客:DockerSwarm集群搭建相关文件准备(这里以一个ocr服务为例)docker-compose.ymlversion:'......
  • 洛谷题单指南-贪心-P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G
    原题链接:https://www.luogu.com.cn/problem/P1090题意解读:两两合并,是典型的哈夫曼编码算法思想,贪心即可。解题思路:要是合并体力消耗最少,就要让尽可能少的果子越晚合并越好,因此,贪心策略为优先选择数量最少的两堆果子合并,一直到剩下一堆果子,把合并过程中的消耗值累加即可,要快速......
  • CNN使用MNIST手写数字识别实战的代码和心得
    CNN(ConvolutionalNeuralNetwork)卷积神经网络对于MNIST手写数字识别的实战代码和心得首先是对代码结构思路进行思路图展示,如下:参数和原理剖析:因为MNIST图片为长和宽相同的28像素,为黑白两色,所以图片的高度为1,为灰度通道。在传入的时候,我定义的BATCH_SIZE为512,所以具体的......
  • 关于RestCloud iPaaS平台的板块详解
    当今的企业分工越来越细,上下游合作越来越紧密、各企业之间的业务系统需要相互协作完成业务、外部API依赖越来越多、同时企业系统运行在多个混合云环境及SaaS中,私有端大量业务系统与云端系统形成了错综复杂的集成关系,企业面临集成技术复杂多样、API管理混乱、故障定位困难、数据推......
  • vscode配置cpplint
    cpplint是Google开发的一个用于检查C++代码风格的工具。它可以自动扫描C++源代码,并提供有关代码规范、风格和错误的反馈。cpplint基于Google的C++编码规范,但也可以配置为符合其他的代码风格指南。注意,cpplint不依赖于vscode存在,可以单独在命令行中使用。安装cpplint:pipinsta......