admin管理员组文章数量:1626405
今天给客户写了一个语音提示的小程序,在XP系统上测试发现请求百度的TTS语音失败,最开始抛出来的异常是“基础连接已经关闭: 发送时发生错误”,在网上找了一些解决方案,其中包括添加以下代码片段
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
结果又出现了“不支持请求的安全协议”,最后就想找一个第三方的https请求模块,放弃C#的WebRequest,最后找到了BouncyCastle.Crypto,可以直接在NuGet中搜索安装即可,但是用它来请求,就需要自己来解析响应的结果,这里稍微麻烦了点
private void Download(string text)
{
TlsClientProtocol protocol = null;
try
{
string host = "fanyi.baidu";
int port = 443;
string request = string.Format("GET /gettts?lan=zh&text={0}&spd=5&source=web HTTP/1.1\r\nHost: {1}\r\n\r\n", text, host);
TcpClient tcpClient = new TcpClient(host, port);
protocol = new TlsClientProtocol(tcpClient.GetStream(), new Org.BouncyCastle.Security.SecureRandom());
protocol.Connect(new MyTlsClient());
//发送http请求头
protocol.Stream.Write(Encoding.UTF8.GetBytes(request), 0, request.Length);
protocol.Stream.Flush();
MemoryStream ms = new MemoryStream();
int len = 0;
int current = 0, pos = 0;
byte[] b = new byte[1024];
string s;
while(true)
{
current = protocol.Stream.ReadByte();
if (current == 10)
{
s = Encoding.UTF8.GetString(b, 0, pos).Trim();
if (s.StartsWith("Content-Length:"))
{
len = Convert.ToInt32(s.Split(' ')[1]);//拿到音频内容的长度
}
else if (s == "")
{
break;
}
pos = 0;
}
b[pos++] = (byte)current;
}
// 准备开始读取音频的内容
byte[] buffer = new byte[1024];
int actual = 0;
int read = 0; //读取了的长度
while ((actual = protocol.Stream.Read(buffer, 0, 1024)) > 0)
{
ms.Write(buffer, 0, actual);
read += actual;
if(len == read)
{
break;
}
}
ms.Position = 0; //移动流的读取位置为0
OnDownloadFinish(ms, null); //下载成功回调,这是我的下载成功回调
}catch(Exception ex)
{
Logger.GetLogger("DownloadAudio").Debug(ex.Message);
OnDownloadFinish(null, ex.Message); //下载失败回调
}
finally
{
if (protocol != null)
protocol.Close();
}
}
}
//辅助类
class MyTlsClient : DefaultTlsClient
{
public override TlsAuthentication GetAuthentication()
{
return new MyTlsAuthentication();
}
}
// Need class to handle certificate auth
class MyTlsAuthentication : TlsAuthentication
{
public TlsCredentials GetClientCredentials(CertificateRequest certificateRequest)
{
// return client certificate
return null;
}
public void NotifyServerCertificate(Certificate serverCertificate)
{
// validate server certificate
}
}
由于我是下载文件,如果你是正常获取网页内容,MemorryStream有转byte数组的方法,然后调用Encoding.UTF8.GetString(bytes, 0, bytes.Length),就获取到响应内容的字符串了。
核心代码我也是从网上找到的,只不过根据我自己的业务需求做了调整
本文标签: 系统XPHTTPSWebRequest
版权声明:本文标题:在XP系统上使用C# WebRequest请求https失败的问题处理 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1728962046a1181549.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论