4

我正在尝试使用 .net SslStream 初始化一个 tls 隧道,但在打开流后我总是收到以下错误:

“无法从传输连接读取数据:已建立的连接被主机中的软件中止。”

在我建立 tls 连接并发送第二条消息之后。

过去四天我一直在寻找答案,但网上没有任何有用的信息!

编辑:我正在尝试连接到 talk.google.com

我正在使用来自 MSDN 的代码示例。唯一的区别是我在使用 tls 之前和何时发送数据,我执行以下操作:

public void SecureStream()
        {
        netStream.Flush();
        sslStream = new SslStream(netStream, false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);

    sslStream.AuthenticateAsClient("talk.google.com");}

编辑:我设法消除了第一个错误(关于我如何处理发送的小错误)现在我总是得到

“无法从传输连接读取数据:已建立的连接被主机中的软件中止。”

编辑2:我没有发送任何空格我重写了消息传递部分,但我仍然遇到同样的问题。

我从

   String streamInit = "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='google.com' version='1.0'>";
        client.Send(streamInit);

然后收到我有以下

  static void client_MessageReceived(SyncronousClient source, string Result)
    {


        if (Regex.IsMatch(Result, "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"><required/></starttls>"))
        {
            String startTlS = "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>";
            source.Send(startTlS);

        }
        else if (Regex.IsMatch(Result, "<proceed xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>"))
        {
            //Do TLS Magic 
            source.SecureStream();
            String streamReInit = "<stream:stream xmlns='jabber:client'xmlns:stream='http://etherx.jabber.org/streams'to='google.com'version='1.0'>";
            source.Send(streamReInit);
        }
        else if (Regex.IsMatch(Result, "<mechanisms xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"))
        {
            //String AuthType = "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-GOOGLE-TOKEN'/>";
            String AuthType = "<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"PLAIN\"/>";
            source.Send(AuthType);
        }}
4

2 回答 2

1

这不太可能是您的问题(除非 .Net 已经开始在幕后进行 SNI),但是当您调用 AuthenticateAsClient 时,请传入您在流的 to 属性中使用的相同域名(在本例中为google.com)。同样,您可能需要gmail.com代替google.com

sslStream.AuthenticateAsClient("gmail.com", null, SslProtocols.Tls, false);

正如 csharptest.net 所暗示的,确保您没有发送额外空格的保活计时器,或者等到 TLS 工作后才启动计时器。我能想象你得到这个错误的唯一另一种方法是,如果你没有服务器实现的密码套件,但我知道 .Net SslStream 适用于 GTalk。

最后,使用现有的 XMPP .Net 库之一(这里列出了5),您可以立即开始编写更多有趣的代码。您即将遇到 .Net XML 系统的不足之处,并且当您开始在一次读取中获得部分节或多个节时,您的基于正则表达式的方法将不起作用。

于 2011-01-26T09:53:13.780 回答
0

这对我来说真的没有意义。如果服务器使用 SSL,则要求客户端在连接时执行 SSL 握手。因此,我不确定您所说的“我之前正在发送数据......”是什么意思。听起来您没有立即调用 AuthenticateAsClient。如果是这种情况,我怀疑这是你的问题。AFAIK,您不能对 SSL 和非 SSL 通信使用相同的套接字/连接连接。服务器需要 SSL,或者它不支持它,它不应该两者都做。

我之前的回答是无知。实际上,该标准似乎确实要求在 SSL 握手初始化之前连接发送和接收数据。他们会这样做真的很奇怪……但无论如何。在简要阅读部分 RFC之后,您似乎应该在关闭“>”之后立即开始 SSL 客户端身份验证。不允许出现尾随空格,这可能是您的问题?

于 2011-01-12T23:19:06.497 回答