概述
在某次项目中通过TCP传输处理XML时,由于TCP传输的特性,大部分的包并不完整,有的只有前半部分、中间部分或后半部分,有的存在粘包问题,导致无法直接读取一包进行解析,于是做了一个小的处理,以完整的一包XML尾标签为标志,判断XML包是否完整,若不完整,则以尾标签进行包分割,将不完整的最后一包保存下来与后面的包进行拼接,从而实现正确解析XML,下面提供一下解决思路。
/// <summary>
/// 解决TCP传输XML,不发送长度时可能导致的包不完整(只有包的前半部分、中间部分、后半部分,即缺首标签或尾标签)、粘包问题
/// </summary>
/// <param name="byteData">通过TCP收到的Byte数组</param>
string remainStrXml = "";//存储上一包剩余的不完整XML
public void dealXmlData(byte[] byteData)
{
string strXml = System.Text.Encoding.UTF8.GetString(byteData, 0, byteData.Length);//存储TCP传输来的一包XML
strXml = remainStrXml + strXml;//将上一包不完整的XML与本包XML拼接
//判断是否包含尾标签,包含则进行处理,不包含则将这包不完整的XML存入remainStrXml,等待与下一包XML拼接
if (strXml.Contains("</DIAG_Meldung>n"))
{
string[] arr = Regex.Split(strXml, "</DIAG_Meldung>n", RegexOptions.IgnoreCase);//以XML尾标签分割各包
string[] strXmlArr = new string[arr.Length - 1];
Array.Copy(arr, 0, strXmlArr, 0, arr.Length - 1);//得到分割后的XML数组,arr.Length - 1的原因是分割后数组的最后一项元素为空
//判断分割后得到的XML数组的最后一项XML是否完整,完整则将remainStrXml置空,表示不需与下一包XML拼接,不完整则将最后一包不完整的XML存入remainStrXml,等待与下一包XML拼接
if (strXml.EndsWith("</DIAG_Meldung>n"))
{
remainStrXml = "";//分割后的XML数组最后一项完整,不需与下一包XML拼接
for (int i = 0; i < strXmlArr.Length; i++)
{
strXmlArr[i] += "</DIAG_Meldung>n";//将分割后的XML数组各项加上尾标签,分别构成完整的XML
//下来就是对完整的一项XML解析的过程,不再详细描述
XmlDocument doc = new XmlDocument();
doc.LoadXml(strXmlArr[i]);
}
}
else
{
remainStrXml = strXmlArr[strXmlArr.Length - 1];//分割后的XML数组最后一项不完整,等待与下一包XML拼接
for (int i = 0; i < strXmlArr.Length - 1; i++)
{
strXmlArr[i] += "</DIAG_Meldung>n";//将分割后的XML数组(不包括最后一项不完整的XML)各项加上尾标签,分别构成完整的XML
//下来就是对完整的一项XML解析的过程,不再详细描述
XmlDocument doc = new XmlDocument();
doc.LoadXml(strXmlArr[i]);
}
}
}
else
{
remainStrXml = strXml;//存储这包不完整的XML,等待与下一包XML拼接
}
}
最后
以上就是无限哑铃为你收集整理的C#解决TCP传输处理XML的包不完整和粘包问题的全部内容,希望文章能够帮你解决C#解决TCP传输处理XML的包不完整和粘包问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复