1

次のコードを使用して、C#のクラスをNetworkStream介して OpenFire サーバーから受信した XML を読み込もうとしています( 1024 バイトごとに呼び出して、保存される XML 部分を増やします)。BeginReadNetworkStreamdatabyte[]

using (var r = XmlReader.Create(new StringReader(Encoding.UTF8.GetString(data)), 
                                new XmlReaderSettings() { Async = true }))
{                    
    while (await r.ReadAsync())
    {
        switch (r.NodeType)
        {
            case XmlNodeType.Element:
                Console.WriteLine(r.LocalName);
                break;

            case XmlNodeType.Text:
                Console.WriteLine(await r.GetValueAsync());
                break;
        }
    }
}

私が受け取った「不完全な」XML は次のようになります。

<?xml version='1.0' encoding='UTF-8'?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="blah" id="d6c0a0b8" xml:lang="en" version="1.0">
<stream:features>
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"></starttls>
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
<mechanism>DIGEST-MD5</mechanism>
<mechanism>PLAIN</mechanism>
<mechanism>ANONYMOUS</mechanism>
<mechanism>CRAM-MD5</mechanism>
</mechanisms>
<compression xmlns="http://jabber.org/features/compress">
<method>zlib</method>
</compression>
<auth xmlns="http://jabber.org/features/iq-auth"/>
<register xmlns="http://jabber.org/features/iq-register"/>
</stream:features>

私は2つの例外を受けています。

  • System.Xml.XmlException: '.'、16 進値 0x00 は無効な文字です
  • System.Xml.XmlException: 'stream' は宣言されていないプレフィックスです

これらの例外が発生するのはなぜですか? どうすれば修正できますか?

使ってみConformanceLevel = ConformanceLevel.Fragmentましたが関係ないようです。

多分私は使用していてXmlReader、そのReadAsync方法は完全に間違っていますか?から直接読み取る方がよいでしょうかNetworkStream(この場合、どのように正しく行われますか)?

現在、1024バイト(バッファのサイズ)ごとに次のように上記のコードを呼び出しています。

private void EndReceive(IAsyncResult asyncResult)
{
    ...
    HandleXMLInput(buffer, nBytes);
    ...
}

アップデート:

BeginReceive/EndReceive がまったく必要ないことに気付きました。を開きNetworkStream、ネットワークからデータが送られてくるのを待つだけで十分AsyncReadです (woohoo! ;))。次のコードはそれをまとめたものです。

socket.BeginConnect(endPoint, new AsyncCallback(EndConnect), null);
private void EndConnect(IAsyncResult asyncResult)
{
    ...
    socket.EndConnect(asyncResult);

    networkStream = new NetworkStream(socket, false);

    HandleXMLInput();

    ...
}
4

1 に答える 1