C# 为什么服务器会强制关闭连接?它期望从客户那里得到什么?
在尝试从手持设备上运行的我的应用程序调用本地网络上运行的服务器应用程序上的REST方法时,失败的原因是“无法为SSL/TLS建立安全通道…System.Net.Sockets.SocketException:远程主机强制关闭了现有连接” 在较新/功能齐全的.NET版本中,您可以将以下代码添加到客户端:C# 为什么服务器会强制关闭连接?它期望从客户那里得到什么?,c#,compact-framework,windows-ce,servicepoint,servicepointmanager,C#,Compact Framework,Windows Ce,Servicepoint,Servicepointmanager,在尝试从手持设备上运行的我的应用程序调用本地网络上运行的服务器应用程序上的REST方法时,失败的原因是“无法为SSL/TLS建立安全通道…System.Net.Sockets.SocketException:远程主机强制关闭了现有连接” 在较新/功能齐全的.NET版本中,您可以将以下代码添加到客户端: ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyE
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
…如图所示,以接受服务器的响应。不过,这在我的Windows CE/Compact Framework应用程序中不可用-尽管ServicePointManager是“已知数量”,但ServerCertificateValidationCallback不可用。这是Windows.NET程序集的一部分,我在此项目中不可用
因此,假设仍然有一种方法可以完成同样的事情(接受ssl服务器的响应),那么在这种情况下如何做到这一点呢
一个建议的解决方法是向我的客户机添加一个类,如下所示:
namespace HHS
{
using System.Net;
using System.Security.Cryptography.X509Certificates;
class TrustAllCertificatesPolicy : ICertificatePolicy
{
public TrustAllCertificatesPolicy()
{
}
public bool CheckValidationResult(ServicePoint sp, X509Certificate cert, WebRequest req,
int problem)
{
return true;
}
}
}
…然后在应用程序启动时调用此函数(例如在主窗体的Load()事件中):
…但我的日志文件中仍然存在此异常:
Message: From FileXferREST.SendHTTPRequestNoCredentials(): Could not establish secure channel for SSL/TLS; Inner Ex: System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.ReceiveNoCheck(Byte[] buffer, Int32 index, Int32 request, SocketFlags socketFlags)
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Connection.System.Net.ISslDataTransport.Receive(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.SslConnectionState.ClientSideHandshake()
at System.Net.SslConnectionState.PerformClientHandShake()
at System.Net.Connection.connect(Object ignored)
at System.Threading.ThreadPool.WorkItem.doWork(Object o)
at System.Threading.Timer.ring()
; Stack Trace: at System.Net.HttpWebRequest.finishGetRequestStream()
at System.Net.HttpWebRequest.GetRequestStream()
at HHS.FileXferREST.SendHTTPRequestNoCredentials(String uri, HttpMethods method, String data, String contentType)
. . .
顺便说一句,TrustAllCertificatesPolicy的(空)构造函数可能没有实际意义,因为它是灰色的
服务器对客户端的期望究竟是什么?为什么服务器会强制关闭连接
使现代化
在尝试确定这是我的客户端代码还是服务器代码中的问题时,我尝试通过Postman点击URL,但得到以下结果:
因此,我按照“在Chrome中导入SSL证书”链接查看这是否有帮助
这[告诉我:
事实证明,有一个更好的解决方案可以解决这个问题,而且它还可以避免在每次启动浏览器时向Chrome添加异常。这就是您的操作方式:
1. Go to the root URL in your browser. For ex. https://localhost
2. Click on the lock icon on the top left in the URL bar.
. . .
但是,在输入https://localhost
在Chrome中,我得到“此网页不可用”
正在尝试http://localhost
取而代之的是(“http”而不是“https”),OTOH,我得到了一个“IIS7”图像,用大量(人类)语言表示“欢迎”
至于第2步(“单击URL栏左上角的锁定图标”),我没有看到这样的东西;我看到的是:
那么我注定要失败了吗?您可能必须明确设置协议(例如`ServicePointManager.SecurityProtocol=SecurityProtocolType.Tls`),谢谢,但我得到了“无法解析SecurityProtocol”和“无法解析SecurityProtocolType”。嗯,可能是CF 1.0/3.5的不同。我已经多年没有使用过3.5了。这是3.5(“下一代”)当前1.0版本)如果浏览器无法访问,则您的应用程序也无法访问。请先从浏览器开始运行。
1. Go to the root URL in your browser. For ex. https://localhost
2. Click on the lock icon on the top left in the URL bar.
. . .