C# 字符串未正确添加到自身。但是他能够比较 string returndata=“”; 字符串FullResponce=“”; bool receivereach=真; while(receiveveray==true) { byte[]inStream=新字节[clientSocket.ReceiveBufferSize]; serverStream.Read(inStream,0,inStream.Length); returndata=System.Text.Encoding.ASCII.GetString(流内); fullresponse+=返回数据; if(fullresponse.Contains(“”) { 再次接收=错误; } } LoadXml(FullResponce);
这是一个循环,用于继续检索数据,直到结束xml块(C# 字符串未正确添加到自身。但是他能够比较 string returndata=“”; 字符串FullResponce=“”; bool receivereach=真; while(receiveveray==true) { byte[]inStream=新字节[clientSocket.ReceiveBufferSize]; serverStream.Read(inStream,0,inStream.Length); returndata=System.Text.Encoding.ASCII.GetString(流内); fullresponse+=返回数据; if(fullresponse.Contains(“”) { 再次接收=错误; } } LoadXml(FullResponce);,c#,xml,string,loops,tcp,C#,Xml,String,Loops,Tcp,这是一个循环,用于继续检索数据,直到结束xml块(“”)包含在发送的所有数据包的FullResponce中。当代码运行时,在我的例子中经过大约5次循环后,(“”)最终包含在文本中 因此if语句运行并最终使receiveReach=false,从而中断循环,从而可以将fullResponse加载到xml中。当它试图加载xml时,会给我一个错误,即xml不完整,当我检查FullResponse文本时,它似乎丢失了除第一个数据包以外的所有内容(甚至丢失了“”,这很奇怪,因为循环中的if语句检测到了它)
“”
)包含在发送的所有数据包的FullResponce中。当代码运行时,在我的例子中经过大约5次循环后,(“”
)最终包含在文本中
因此if语句运行并最终使receiveReach=false,从而中断循环,从而可以将fullResponse加载到xml中。当它试图加载xml时,会给我一个错误,即xml不完整,当我检查FullResponse文本时,它似乎丢失了除第一个数据包以外的所有内容(甚至丢失了“”
,这很奇怪,因为循环中的if语句检测到了它)
因为它缺少一半的xml,这就是为什么它会给出一个错误,但是为什么完整的响应不能正确地添加到自身中呢?代码fullresponse+=returndata似乎只运行一次,就是这样
另一件需要注意的事情是,当我在这个循环的开头设置一个断点,并手动检查所有代码,直到它尝试加载到xml中,它工作得非常好,FullResponse字符串是完整的,并且包含所有正确的数据
这就像当我让程序一步一步地运行时,它能够正确地将returndata添加到fullresponse,但是当没有断点并且调试正常时,它会给出错误
发生了什么以及如何修复此问题?您的代码存在许多问题,但最大的问题(也是导致问题的原因)是您没有考虑到实际接收的字节数。这会导致字符串中存在空字符,然后一些组件会将空字符解释为字符串的结尾。(.NET字符串被计数,而不是NULL终止,但是仍然有很多代码,在字符串的中间没有期望一个空字符)。< /P> 您应该更改循环,使其看起来更像:
string returndata = "";
string FullResponce = "";
bool RecieveAgain = true;
while (RecieveAgain == true)
{
byte[] inStream = new byte[clientSocket.ReceiveBufferSize];
serverStream.Read(inStream, 0, inStream.Length);
returndata = System.Text.Encoding.ASCII.GetString(inStream);
FullResponce += returndata;
if (FullResponce.Contains("< /Program>"))
{
RecieveAgain = false;
}
}
xmlDoc.LoadXml(FullResponce);
注意:除了空字符的问题外,上述版本修复了原始情况下的另一个问题,即在循环中使用字符串连接。这样做会导致严重的性能和内存消耗问题;使用StringBuilder
是在循环中连接文本的适当方法
注意:只要您确定您的XML只有ASCII字符,以上内容就可以了。但请注意,UTF8和UTF16现在很常见,从技术上讲,XML就是这些格式之一,而且有很多XML中包含非ASCII字符。您可能需要仔细检查XML的编码,并确保使用的是正确的编码
注意:在上述代码中,它使用流结束指示(即读取操作返回字节计数0)来终止循环。无论如何,你都应该检查一下。而且StringBuilder
无法检查某些特定文本的包含情况,因此您以前的方法与StringBuilder
的使用不兼容
现在,您可能会想“嘿,可能还有更多的数据!为什么不接受性能影响,并使用字符串连接和Contains()
?”。好的,答案是:如果在XML结束后有可能出现更多的数据,那么您需要一种比查找close标记更可靠的方法来检测XML结束
Stream
对象无法知道它应该在XML末尾停止读取您的数据,因此最后一次读取操作(带有XML的最终关闭标记的操作)可以(也可能会)包含XML后面的部分数据
这意味着你会有两个问题:
StringBuilder
,并且不必在字符串中搜索该关闭标记
我将提供关于后一方面的更多细节,但您在问题中没有提供足够的信息。如果您在这方面需要帮助,请发布新问题,并确保提供适当的详细信息。有关如何更好地表达问题的建议,请参阅和。您的代码存在许多问题,但最大的问题(也是导致问题的原因)是您没有考虑到实际接收的字节数。这会导致字符串中存在空字符,然后一些组件会将空字符解释为字符串的结尾。(.NET字符串被计数,而不是NULL终止,但是仍然有很多代码,在字符串的中间没有期望一个空字符)。< /P> 您应该更改循环,使其看起来更像这样:
StringBuilder fullResponse = new StringBuilder();
byte[] buffer = new byte[clientSocket.ReceiveBufferSize];
int bytesRead;
while ((bytesRead = serverStream.Read(buffer, 0, buffer.Length)) > 0)
{
string textRead = System.Text.Encoding.ASCII.GetString(buffer, 0, bytesRead);
fullResponse.Append(textRead);
}
xmlDoc.LoadXml(fullResponse.ToString());