2013-11-24 149 views
0

我试图从/向服务器读/写使用tcp套接字连接的xml。它给我错误根元素缺失。我知道那里有xmpp/jabber库,但我正在寻找一个简单的自定义解决方案,如何在一般情况下做到这一点,以及如何解决我的代码中的错误。 我将不胜感激,如果有人可以帮助我:)通过Socket c读取xml#

 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(); 
       } 
     } 
+0

您是否检查过发送的完整xml文档? – Bauss

回答

1

我的猜测是,要么XMLReader有一个关于接收到的数据(IE的缓存大小错误的假设:预计可以读取这两种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(); 
     } 
    } 
}