带base64 innertext的c#XmlReader
好的,这是我的问题。 我正在尝试截图,将其添加到xmldocument中,通过套接字发送,然后用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) {
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,但作为收件人