Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带base64 innertext的c#XmlReader_C#_Xml_Byte_Xmlreader - Fatal编程技术网

带base64 innertext的c#XmlReader

带base64 innertext的c#XmlReader,c#,xml,byte,xmlreader,C#,Xml,Byte,Xmlreader,好的,这是我的问题。 我正在尝试截图,将其添加到xmldocument中,通过套接字发送,然后用XmlReader读取 这里有一些代码 服务器端 private void SendRandomData(object data) { XMLShitSock sock = data as XMLShitSock; if(sock != null) { int incnum = 0; while(sock.Connected) {

好的,这是我的问题。 我正在尝试截图,将其添加到xmldocument中,通过套接字发送,然后用XmlReader读取

这里有一些代码

服务器端

private void SendRandomData(object data)
{
    XMLShitSock sock = data as XMLShitSock;
    if(sock != null)
    {
        int incnum = 0;
        while(sock.Connected)
        {
            XmlDocument doc = new XmlDocument();
            XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
            doc.AppendChild(docNode);

            XmlNode productsNode = doc.CreateElement("image");

            productsNode.InnerText = Convert.ToBase64String(Program.CaptureImageToBytes(new Point(0, 0), new Rectangle(0, 0, Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height), ImageFormat.Png));
            doc.AppendChild(productsNode);
            string s = XMLShitSock.GetXmlString(doc);
            doc.Save("temp.xml");
            sock.WriteXMLMessage(doc);
            incnum++;
            Thread.Sleep(5000);
        }
    }
}
sock.WriteXMLMessage

public bool WriteXMLMessage(XmlDocument doc)
{
    try
    {
        ShittySocket.Client.Send(Encoding.ASCII.GetBytes(GetXmlString(doc)));
        return true;
    }
    catch(SocketException se)
    {
        this.Close();
        return false;
    }
}
读取输入

private void doInput()
{
    MemoryStream ms = new MemoryStream();
    NetworkStream ns = new NetworkStream(ShittySocket.Client, false);
    while(_connected)
    {
        if(ns.DataAvailable)
        {
            StreamReader sr = new StreamReader(ns);
            char[] b = new char[512];
            int nread = sr.Read(b, 0, 512);

            ms.Write(System.Text.Encoding.ASCII.GetBytes(b, 0, nread), 0, nread);
            ms.Seek(0, System.IO.SeekOrigin.Begin);

            XmlReaderSettings xrs = new XmlReaderSettings();

            XmlReader reader = XmlReader.Create(ms);
            if(reader.Read())
            {
                XmlDocument objXmlDocument = new XmlDocument();
                objXmlDocument.Load(reader);
                onInput(this, objXmlDocument);
                ms.Close();
                ms = new MemoryStream();
            }
        }
        Thread.Sleep(100);
    }
}
我遇到的问题是doInput()中有一个错误,表示到达文档结尾时没有找到标记。我保存了xml文件并查看了它,它是存在的,除了实际标记中的字符之外,我甚至没有找到任何<字符,所以我不确定这里发生了什么。我显然错过了什么

此外,如果您对语义或编码风格有任何顾虑,或者任何实际上没有回答问题的东西,请将其作为注释,因为它不是答案

也 我已经看完了->>我希望有一种更好的方法来处理base64数据,而不是将其与XMLDocument本身分离。谢谢。

试试看

ms.Position = 0; 
而不是

ms.Seek(0, System.IO.SeekOrigin.Begin);
doInput()中

你也可以试着更换

Encoding.ASCII

或者用以下代码替换大量代码:

    private void doInput()
    {
        NetworkStream ns = new NetworkStream(ShittySocket.Client, false);
        while (_connected)
        {
            if (ns.DataAvailable)
            {
                using (StreamReader sr = new StreamReader(ns, System.Text.Encoding.UTF8))
                {
                        XmlDocument objXmlDocument = new XmlDocument();
                        objXmlDocument.LoadXml(sr.ReadToEnd());
                        onInput(this, objXmlDocument);
                }
            }
            Thread.Sleep(100);
        }
    }
试一试

而不是

ms.Seek(0, System.IO.SeekOrigin.Begin);
doInput()中

你也可以试着更换

Encoding.ASCII

或者用以下代码替换大量代码:

    private void doInput()
    {
        NetworkStream ns = new NetworkStream(ShittySocket.Client, false);
        while (_connected)
        {
            if (ns.DataAvailable)
            {
                using (StreamReader sr = new StreamReader(ns, System.Text.Encoding.UTF8))
                {
                        XmlDocument objXmlDocument = new XmlDocument();
                        objXmlDocument.LoadXml(sr.ReadToEnd());
                        onInput(this, objXmlDocument);
                }
            }
            Thread.Sleep(100);
        }
    }

看起来您假设整个数据将在一个512字节的块中读取。因此,如果实际数据的长度(例如)为513字节,那么您将无法在文档末尾获得右括号>,因此XML解析器将失败

我不知道您使用的是哪种类型的网络流,但如果是普通套接字,那么您需要某种分隔符来知道何时到达一个“发送”的末尾和下一个“发送”的开头,因为普通套接字只是一个数据管道。通过一次读取,您可能会收到半个、一个、两个、三个比特的实际块


方便的是,您有一个以结束标记形式表示的分隔符。

看起来您假设整个数据将在一个512字节的块中读取。因此,如果实际数据的长度(例如)为513字节,那么您将无法在文档末尾获得右括号>,因此XML解析器将失败

我不知道您使用的是哪种类型的网络流,但如果是普通套接字,那么您需要某种分隔符来知道何时到达一个“发送”的末尾和下一个“发送”的开头,因为普通套接字只是一个数据管道。通过一次读取,您可能会收到半个、一个、两个、三个比特的实际块


方便的是,您有一个结束标记形式的分隔符。

关于
doInput()
的两件事:

  • XmlReaderSettings xrs=新的XmlReaderSettings()是不需要的,因为在后续的
    XmlReader.Create()
    中不使用它。除非你先设置它的一些属性,否则没有必要这样做

  • 您不能假设
    reader.Read()
    就在这里读取整个xml。使用
    XmlReader
    必须执行
    Read()
    ,直到得到
    false
    的响应


  • 使用(var reader=XmlReader.Create(…){…}
    进行
    也是一个好主意,这样当它完成读取时,一切都会很好地包装起来。

    关于
    doInput()
    的两件事:

  • XmlReaderSettings xrs=新的XmlReaderSettings()是不需要的,因为在后续的
    XmlReader.Create()
    中不使用它。除非你先设置它的一些属性,否则没有必要这样做

  • 您不能假设
    reader.Read()
    就在这里读取整个xml。使用
    XmlReader
    必须执行
    Read()
    ,直到得到
    false
    的响应


  • 使用(var reader=XmlReader.Create(…){…}
    进行
    也是一个好主意,这样当它完成读取时,一切都会很好地包装起来。

    好的,所以我想出了一个解决方案。 下面是函数

    public static XmlDocument GrabXmlDocFromStream(StreamReader reader)
    {
        using(MemoryStream ms = new MemoryStream())
        {
            byte b = 0;
            while(!reader.EndOfStream)
            {
                b = (byte)reader.Read();
                ms.WriteByte(b);
                ms.Seek(0, System.IO.SeekOrigin.Begin);
    
                using(XmlReader xmlreader = XmlReader.Create(ms))
                {
                    XmlDocument doc = new XmlDocument();
                    try
                    {
                        if(Encoding.ASCII.GetChars(new byte[1] { b })[0] == '>')
                        {
                            if(xmlreader.Read())
                            {
                                XmlDocument objXmlDocument = new XmlDocument();
                                objXmlDocument.Load(xmlreader);
                                return objXmlDocument;
                            }
                        }
                    }
                    catch(XmlException xe) { }
                }
            }
        }
        return null;
    }
    
    你是这样用的

                using(NetworkStream ns = new NetworkStream(ShittySocket.Client, false))
    {
                using(StreamReader sr = new StreamReader(ns))
                {
                    XmlDocument xdoc = new XmlDocument();
                    while(xdoc != null)
                    {
                        xdoc = Program.GrabXmlDocFromStream(sr);
                        if(xdoc != null)
                            Program.Handle_Document(xdoc);
                    }
                }
    }
    
    下面是代码中提到的另外两个函数

        public static string GetXmlString(XmlDocument doc)
        {
            StringWriter sw = new StringWriter();
            XmlTextWriter xw = new XmlTextWriter(sw);
            doc.WriteTo(xw);
            return sw.ToString();
        }
    
        public static void Handle_Document(XmlDocument doc)
        {
            MessageBox.Show(GetXmlString(doc));
        }
    
    这可能不是最好的解决方案,但我使用了一行if(Encoding.ASCII.GetChars(新字节[1]{b})[0]=='>'),这样我就不会对每个字符都产生异常。据我所知,以这种方式使用try-catch并不完全是解决问题的“正确”方法,但它是有效的,而且我认为我可以承受轻微的时间损失。
    任何想法都很好,如果你发现这个有问题,请告诉我。谢谢。

    好的,我想出了一个解决办法。 下面是函数

    public static XmlDocument GrabXmlDocFromStream(StreamReader reader)
    {
        using(MemoryStream ms = new MemoryStream())
        {
            byte b = 0;
            while(!reader.EndOfStream)
            {
                b = (byte)reader.Read();
                ms.WriteByte(b);
                ms.Seek(0, System.IO.SeekOrigin.Begin);
    
                using(XmlReader xmlreader = XmlReader.Create(ms))
                {
                    XmlDocument doc = new XmlDocument();
                    try
                    {
                        if(Encoding.ASCII.GetChars(new byte[1] { b })[0] == '>')
                        {
                            if(xmlreader.Read())
                            {
                                XmlDocument objXmlDocument = new XmlDocument();
                                objXmlDocument.Load(xmlreader);
                                return objXmlDocument;
                            }
                        }
                    }
                    catch(XmlException xe) { }
                }
            }
        }
        return null;
    }
    
    你是这样用的

                using(NetworkStream ns = new NetworkStream(ShittySocket.Client, false))
    {
                using(StreamReader sr = new StreamReader(ns))
                {
                    XmlDocument xdoc = new XmlDocument();
                    while(xdoc != null)
                    {
                        xdoc = Program.GrabXmlDocFromStream(sr);
                        if(xdoc != null)
                            Program.Handle_Document(xdoc);
                    }
                }
    }
    
    下面是代码中提到的另外两个函数

        public static string GetXmlString(XmlDocument doc)
        {
            StringWriter sw = new StringWriter();
            XmlTextWriter xw = new XmlTextWriter(sw);
            doc.WriteTo(xw);
            return sw.ToString();
        }
    
        public static void Handle_Document(XmlDocument doc)
        {
            MessageBox.Show(GetXmlString(doc));
        }
    
    这可能不是最好的解决方案,但我使用了一行if(Encoding.ASCII.GetChars(新字节[1]{b})[0]=='>'),这样我就不会对每个字符都产生异常。据我所知,以这种方式使用try-catch并不完全是解决问题的“正确”方法,但它是有效的,而且我认为我可以承受轻微的时间损失。
    任何想法都很好,如果你发现这个有问题,请告诉我。谢谢。

    我可以使用sr.ReadToEnd(),但是当它处理读取命令并且没有所有数据时会发生什么。TcpIp套接字不发送数据包,所以我不会得到一个产生错误的半文档吗?同样,如果我读到流的末尾,那不是一直读到连接关闭,因为网络流的结尾意味着它关闭了吗?我现在就知道了。那么,您只需读取前512个字节,然后从中创建xml文档?还是不明白:)呸,关键是要在reader.Read()返回true之前追加数据,我认为这表示完成了xmldocument@Kelton52,是的,您正在读取一个无底桶,需要搜索返回的数据,以查看是否有您感兴趣的整个数据块—在本例中是XML文档。但是,同一个数据包中可能有另一个数据包的开始,或者一个文档的结束和下一个文档的开始。作为发件人,我可以写12345,但作为收件人