【问题标题】:Reading Xml over Socket c#通过 Socket c# 读取 Xml
【发布时间】:2013-11-24 23:25:48
【问题描述】:

我正在尝试使用 tcp 套接字连接从/向服务器读取/写入 xml。它给了我错误根元素丢失。我知道那里有 xmpp/jabber 库,但我正在寻找一个简单的自定义解决方案,通常如何执行此操作以及如何修复我的代码中的错误。 如果有人可以帮助我,我将不胜感激:)

        private void WritePreauthStreamInit(XmlWriter writer, string domain)
        {               
            this.socketStream = new NetworkStream(this._socket);

            XmlWriter writer1 = XmlWriter.Create(this.socketStream);
            writer1.WriteStartElement("stream", "stream", "http://etherx.jabber.org/streams");
            writer1.WriteAttributeString("to", domain);
            writer1.WriteAttributeString("version", "1.0");
            writer1.WriteStartElement("start-ack");
            writer1.WriteEndElement();
            writer1.Flush();

            XmlReader reader1 = XmlReader.Create(this.socketStream);
                while (reader1.Read()) //Exception: Root element is missing
                {
                    string xml = reader1.Read().ToString();
                }
        }

【问题讨论】:

  • 您检查过您发送的完整 xml 文档吗?

标签: c# xml sockets xmpp


【解决方案1】:

我的猜测是,要么 XmlReader 对接收数据的缓冲区大小有错误的假设(即:它希望在开始处理数据之前读取 4096 字节或到达流的末尾),要么服务器没有发送将要发送的内容一份有效的文件。

无论哪种方式,您都可以通过实现将网络流量转储到磁盘的日志流包装器或使用 Wireshark 或类似工具来检查。

public class LoggingStreamWrapper : Stream
{
    private Stream baseStream;
    private TextWriter twLog;
    private Encoding baseEncoding;

    public LoggingStreamWrapper(Stream baseStream, TextWriter twLog)
        : this(baseStream, twLog, Encoding.UTF8)
    {
    }

    public LoggingStreamWrapper(Stream baseStream, TextWriter twLog, Encoding encoding)
    {
        if (baseStream == null)
            throw new ArgumentNullException("baseStream");
        if (twLog == null)
            throw new ArgumentNullException("twLog");

        this.baseStream = baseStream;
        this.twLog = twLog;
        this.baseEncoding = encoding;
    }

    public override bool CanRead
    {
        get { return baseStream.CanRead; }
    }

    public override bool CanSeek
    {
        get { return baseStream.CanSeek; }
    }

    public override bool CanWrite
    {
        get { return baseStream.CanWrite; }
    }

    public override void Flush()
    {
        baseStream.Flush();
        twLog.WriteLine("Flushed stream");
        twLog.Flush();
    }

    public override long Length
    {
        get { return baseStream.Length; }
    }

    public override long Position
    {
        get { return baseStream.Position; }
        set
        {
            baseStream.Position = value;

            twLog.WriteLine(string.Format("Set position to {0}", value));
            twLog.Flush();
        }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        var bRead = baseStream.Read(buffer, offset, count);

        if (bRead > 1)
        {
            twLog.WriteLine(string.Format("Read {0} bytes from stream: {1}\r\n{2}", bRead,
                getText(buffer, offset, bRead),
                Convert.ToBase64String(buffer, offset, bRead, Base64FormattingOptions.InsertLineBreaks)));
            twLog.Flush();
        }
        else
        {
            twLog.WriteLine(string.Format("Read {0} bytes from stream", bRead));
            twLog.Flush();
        }

        return bRead;
    }

    private string getText(byte[] buffer, int offset, int bRead)
    {
        try
        {
            return baseEncoding.GetString(buffer, offset, bRead);
        }
        catch
        {
            return "{ERROR: Could not convert to text}";
        }
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        var newpos = baseStream.Seek(offset, origin);

        twLog.WriteLine(string.Format("Seeked to {0} relative to {1}.  New offset {2}", offset, origin, newpos));
        twLog.Flush();

        return newpos;
    }

    public override void SetLength(long value)
    {
        baseStream.SetLength(value);

        twLog.WriteLine(string.Format("Set length to {0}", value));
        twLog.Flush();
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        baseStream.Write(buffer, offset, count);

        twLog.WriteLine(string.Format("Wrote {0} bytes to stream: {1}\r\n{2}", count,
            getText(buffer, offset, count),
            Convert.ToBase64String(buffer, offset, count, Base64FormattingOptions.InsertLineBreaks)));
        twLog.Flush();
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);

        if (disposing)
        {
            twLog.Dispose();
            baseStream.Dispose();
        }
    }
}

【讨论】:

    猜你喜欢
    • 2012-12-02
    • 1970-01-01
    • 2012-01-30
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    相关资源
    最近更新 更多