4

.net SslStream で tls トンネルを初期化しようとしていますが、ストリームを開いた後、常に次のエラーが発生します。

「トランスポート接続からデータを読み取れません: 確立された接続は、ホスト マシンのソフトウェアによって中止されました。」

TLS 接続を確立した後、2 番目のメッセージを送信した後。

この 4 日間、答えを探していましたが、役立つ情報がオンラインにありません!

編集: 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 ライブラリの 1 つ (ここに5 つリストされています) を使用すると、もっと楽しいコードをすぐに書き始めることができます。.Net XML システムの不備に直面しようとしています。単一の読み取りで部分的なスタンザまたは複数のスタンザを取得し始めると、正規表現ベースのアプローチは機能しません。

于 2011-01-26T09:53:13.780 に答える
0

それは本当に私には意味がありません。サーバーが SSL を使用している場合、クライアントは接続時に SSL ハンドシェークを実行する必要があります。したがって、「以前にデータを送信しています...」という意味がわかりません。AuthenticateAsClient をすぐに呼び出さないようです。この場合、それがあなたの問題だと思います。私の知る限り、SSL通信と非SSL通信の両方に同じソケット/接続接続を使用することはできません。サーバーが SSL を必要とするか、サポートしていないかのいずれかです。両方を行うべきではありません。

上記の私の以前の答えは無知でした。実際、標準では、SSL ハンドシェイクの初期化の前に、接続がデータを送受信する必要があるようです。彼らがそんなことをするのは本当に奇妙だ...しかし、何でも。RFC の一部をざっと読んだ後、'>' を閉じた直後に SSL クライアント認証を開始する必要があるようです。あなたの問題かもしれない末尾の空白は許可されていませんか?

于 2011-01-12T23:19:06.497 に答える