怎么办HTTPS使用的TcpClient就像HttpWebRequest的呢? [英] How to do HTTPS with TcpClient just like HttpWebRequest does?

查看:345
本文介绍了怎么办HTTPS使用的TcpClient就像HttpWebRequest的呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经有了基于TcpClient的通信系统,并且除了当它做HTTPS到一个特定的IP为它的伟大工程。然后,它开始出现故障。

I've got a communication system based on TcpClient, and it works great except for when it's doing HTTPS to a particular IP. Then it starts to fail.

通过使用浏览器或HttpWebRequest的,我没有问题做HTTPS到该IP。

By using a browser or HttpWebRequest, I have no problems doing HTTPS to that IP.

我创建了一个测试程序,以缩小我的问题到它的基本精髓,你可以在这里看看,如果你想:的 TestViaTcp

I've created a test program to narrow my problem down to its basic essence, you can have a look at it here if you want: TestViaTcp

这是测试程序完全适用于基本的HTTP到同一个IP,它总是产生对请求的成功响应。我把它放在一个循环,与按键触发它,它会继续成功整天。当我切换HTTPS,我得到一个循环模式。它会工作,那么就不会,成功后失败后成功来回整天

That test program works perfectly for basic HTTP to the same IP, it always produces a successful response to the request. I put it in a loop, trigger it with a keypress, it will continue to succeed all day long. As soon as I toggle the HTTPS, I get a recurring pattern. It'll work, then it won't, success followed by failure followed by success back and forth all day long.

根据具体的故障我不断收到是这个:

The particular failure I keep getting is this one:

{"Authentication failed because the remote party has closed the transport stream."}
    [System.IO.IOException]: {"Authentication failed because the remote party has closed the transport stream."}
    Data: {System.Collections.ListDictionaryInternal}
    HelpLink: null
    InnerException: null
    Message: "Authentication failed because the remote party has closed the transport stream."
    Source: "System"
    TargetSite: {Void StartReadFrame(Byte[], Int32, System.Net.AsyncProtocolRequest)}

和这里是连接到该堆栈跟踪:

And here's the stack trace attached to that:

   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
   at DeriveClassNameSpace.Services.Web.TcpMessaging.TestViaTcp(IPEndPoint endpoint, String auth, Boolean useSSL)

HttpWebRequest和浏览器都(IIRC)使用Win32库来处理后面的反复沟通,同时TcpClient的是使用托管.NET Socket类(据我所知),所以我肯定有他们之间有很大的差异。我确实需要的TcpClient做到这一点,所以很遗憾我不能只是使用HttpWebRequest的,因为我知道我可以使它发挥作用。

HttpWebRequest and the browser are both (IIRC) using the Win32 libraries to handle the back-and-forth communication, while TcpClient is (AFAIK) using the managed .net Socket class, so I'm sure there's a large difference between them. I do need to do this with TcpClient, so unfortunately I can't just "use HttpWebRequest since I know I can make it work".

最大的提示是什么问题是在这里很可能是的作品,不,工作,没有的格局,是什么造成的?我能做些什么来避免我收到IOException异常?有没有办法让永远的作品的行为,我可以看到我做的HttpWebRequest?

The biggest hint as to what the problem is here is likely the "works, doesn't, works, doesn't" pattern, what's causing that? What can I do to avoid the IOException I'm getting? Is there some way to get the "always works" behaviour that I can see when I do the HTTPS with HttpWebRequest?

应该有什么我可以TcpClient的做的就是它采取行动并作出反应,就像HttpWebRequest的做法,但我还没有。任何想法

There should be something I can do with TcpClient to get it to act and react just like HttpWebRequest does, but I'm not there yet. Any ideas?

请注意:?我与通信的服务器配置为侦听的端口上,并预计什么协议,但在其他方面完全不可修改

Note: The server I'm communicating with is configurable as to what port it listens on and what protocol it expects, but is otherwise completely unmodifiable.

另外请注意:我读过.NET 3.5了这一具体问题与SslStream SP1之前,但我有SP1和我的计划是建立目标定位3.5,所以我假设这不是一个已知的错误我运行到这里。

Also note: I've read that .net 3.5 had this particular issue with SslStream before SP1, but I've got SP1 and my program is built targetting 3.5 so I'm assuming that this isn't a 'known bug' I'm running into here.

推荐答案

难道你不知道吧, 之后的我花时间形成的问题是,当我偶然发现了答案

Wouldn't you know it, after I spend the time forming the question is when I stumble upon the answer.

下面是有关的文件:的 jpsanders博客条目

Here's the relevant documentation: jpsanders blog entry

最重要的部分是这样的:

The important part was this:

如果从异常堆栈包括类似于此信息:System.IO.IOException:身份验证失败,因为远程方已关闭传输流。这可能是该服务器是一个较旧的服务器不理解TLS和所以你需要如915599 KB指定这样的事情来改变这一点:ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;之前您在您的应用程序的任何HTTPS调用。

所以,我改变我接受协议,以这样的:(删除TLS的可能性)

So I change my accepted protocols to this: (removing the possibility of TLS)

SslProtocols protocol = SslProtocols.Ssl2 | SslProtocols.Ssl3;

和一切伟大工程。结果
我被允许TLS,所以它会试图说首先,服务器不支持它,所以流被关闭。下一次它使用SSL2或SSL3,一切都很好。或类似的东西。它的工作原理,我是一个快乐的熊猫。

And everything works great.
I was allowing TLS, so it tries that first, and the server doesn't support it, so the stream is closed. The next time it uses Ssl2 or Ssl3 and everything's fine. Or something like that. It works, I'm a happy panda.

这篇关于怎么办HTTPS使用的TcpClient就像HttpWebRequest的呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆