I am trying to read in XML that I receive as NetworkStream
from an OpenFire server via BeginRead
of the NetworkStream
class in C# with following code (I call it every 1024 bytes to give it more XML parts which are saved in data
(which is byte[]
)).
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;
}
}
}
The 'incomplete' XML I am receiving looks like follows.
<?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>
I am getting 2 exceptions.
- System.Xml.XmlException: '.', hexadecimal value 0x00, is an invalid character
- System.Xml.XmlException: 'stream' is an undeclared prefix
Why am I getting these exceptions? How do I fix them?
I tried using ConformanceLevel = ConformanceLevel.Fragment
but this seems to have nothing to do with it.
Maybe I am using XmlReader
and its ReadAsync
method completely wrong? Would it be better to read directly from the NetworkStream
(if this is the case how is it done correctly)?
Currently I am calling the above code like follows every 1024 bytes (size of the buffer).
private void EndReceive(IAsyncResult asyncResult)
{
...
HandleXMLInput(buffer, nBytes);
...
}
Update:
I just realized that no BeginReceive/EndReceive is needed at all. It is sufficient to just open the NetworkStream
and then wait for data coming from the network in AsyncRead
(woohoo! ;)). The following code sums it up.
socket.BeginConnect(endPoint, new AsyncCallback(EndConnect), null);
private void EndConnect(IAsyncResult asyncResult)
{
...
socket.EndConnect(asyncResult);
networkStream = new NetworkStream(socket, false);
HandleXMLInput();
...
}