我遇到了类似于this的问题-我试图解析从TCP接收到的XML而没有任何定界符,并且以任何方式知道我是否接收到完整或部分XML。现在,我采用了以下方法-继续将接收到的数据添加到字符串中,尝试使用var xmls = Regex.Split(newData, @"(?=<\?xml)");
对其进行拆分,并尝试解析来自split的每个字符串-如果解析正确,可以,但是如果没有,则将非完整的XML输入缓冲区并继续。这是执行此操作的接收代码的一部分:
string inputBuffer = "";
private void TcpEndReceive(IAsyncResult result)
{
lock (tcpLock)
{
int bytesAvailable = 0;
try
{
bytesAvailable = tcpClient.GetStream().EndRead(result);
}
catch (Exception ex)
{
log.Error("TcpEndReceive: error endRead, ", ex);
OnStatusChanged(EReceiverStatus.ConnectionError);
TcpClose();
}
if (bytesAvailable >= 0)
{
try
{
var newData = System.Text.ASCIIEncoding.ASCII.GetString(tcp_data, 0, bytesAvailable);
if (!ParseMessage(newData))
{
var xmls = Regex.Split(newData, @"(?=<\?xml)");
foreach (var xml in xmls)
{
if (xml.Length == 0) continue;
if (!ParseMessage(xml))
{
inputBuffer += xml;
}
}
if (inputBuffer.Length == 0) return;
if (ParseMessage(inputBuffer))
{
inputBuffer = "";
}
}
}
catch (Exception ex)
{
log.Error("TcpEndReceive:error reading data, ", ex);
OnStatusChanged(EReceiverStatus.ConnectionError);
TcpClose();
}
}
}
TcpBeginReceive();
}
现在,这看起来不错,但事实并非如此-如果消息的一部分混乱,则此方法将无效。有人知道如何解决吗?如果邮件解析正常,ParseMessage
返回true。同样,您可能会通过一次传输收到一部分消息,整个消息(是!)甚至是多条消息(XML)。
欢迎任何建议,想法或帮助。请求是“简单的”-从TCP流中接收全部或部分XML,解析可用的XML,然后等待其他片段到达,以进行无法解析的片段。在每个(有效)XML的开头,您只能使用可靠的“定界符” <?xml
。
[edit]-其他说明-我无法控制发送给我的数据-我无法添加分隔符,分隔符或其他任何内容。我只能接收可能或可能不是完整XML的字符串。一些消息包含Base64编码的图像,但它们不适合一条消息-首先,您开始使用XML,然后几毫秒后,您获得Base64图像(没有任何后续数据表明),然后结束XML。就像我说的那样,在有效XML的开始(当然还有下一个开始),只有可靠的信号是<?xml
。此外,还有一个小问题,即消息类型多种多样,具有不同的根元素,因此您不能仅反序列化为class Message
-您有10-15种不同的消息。在我的示例中,ParseMessage
接收字符串,找到根元素和第一个节点,并根据它反序列化消息,从而获得有用的信息。