通过 Socket c# 读取 Xml

Posted

技术标签:

【中文标题】通过 Socket c# 读取 Xml【英文标题】:Reading Xml over Socket c# 【发布时间】: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 文档吗? 【参考方案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\n2", 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\n2", 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();
        
    

【讨论】:

以上是关于通过 Socket c# 读取 Xml的主要内容,如果未能解决你的问题,请参考以下文章

通过c#读取xml的多个子节点

使用C#进行XML文档读取

C# 读取XML注释

UWP c# 从 StreamSocket 读取 XML

通过 c# 与 socket.io 服务器通信

用C#把word中的表格数据读取到xml文件