2011-10-22 149 views
1

这些天来,我面临一个字节数组编码字符串的问题。 我使用一个套接字接收从服务器到缓冲区的数据,然后创建一个MemoryStream以将数据从此缓冲区读取到具有固定长度30的tempBuffer,然后从tempBuffer的GetString中读取数据。Encoding.UTF8.GetString工作出错,从套接字接收数据

byte tempBuff = new byte[30]; 
streamReader.Read(tempBuff, 0, 30); 
string moTaSkill = Encoding.UTF8.GetString(tempBuff); 

的我用一个文本框显示如下字符串:

tbSkill.Text = moTaSkill; 

它始终显示错误的文本框:

  1. 当调试我看到moTaSkill =“的技巧英雄“
  2. 当显示在文本框上时,它只是”技能“或有时是”技能“或”技能的“

我试着创建tempBuffer,其长度等于我将收到的字符串的长度。但没有成功。

任何人可以告诉我一些解决方案来解决它吗?

回答

1

两个问题。您忘记了注意Read()调用的返回值。它告诉你有多少实际字节被复制到tempBuf。然后,您应该在GetString()方法中使用它,以避免转换零。

第二个问题是TCP连接提供了一个网络,而不是数据包。每个Read()调用将获得多少个字节是非常不可预测的。同样,返回值告诉你这一点。它只会匹配服务器意外传输的字节数。你需要继续调用Read(),直到你全部获得它们。与此相关的主要问题是,你不一定知道阅读完成的时间。服务器需要传递一些额外的数据,以便接收者知道。就像先发送字符串长度一样。

0

你应该在你的代码中使用flush命令,因为所有的缓冲区都应该被重置。

上传,你填充缓冲区的代码

0

我们将需要更多的代码,但我会告诉你发生了什么。

您的TextBox正在使用标准的Windows控件。标准窗口控件在第一个\0字符(C/C++中的nul)停止写入。这是因为他们使用的是“C String”,它们是nul终止的字符数组。你的字符串包含这些,可能是因为你在某处错误地复制了它。 Visual Studio显示完整的字符串,因为他可以显示前夕\0个字符。尝试做:int ix = moTaSkill.IndexOf('\0');

+0

谢谢大家的帮忙,原因是字符串末尾为空字符。将数据复制到缓冲区时我做了一些错误。 – lemycanh

0

这里的主要问题是,你认为读取填充你的缓冲区;这是不安全的。您必须调用Read并检查返回值以查看读取的字节数。所有你保证是< = 0(对于EOF)或> 0和< =计数(如果不是EOF)。这通常意味着循环,每次添加一个偏移量并减少计数。为了解决这个问题,通常需要指出(首先)要跟踪的数据的长度,以便知道何时停止。您也可以使用EOF停止,但显然只有当频道不是长时间运行的双向会话时才会停止。

你也应该只尝试编码真实的数据;如果读取了14个字节,则必须告诉编码器仅查看14个字节,即使缓冲区较大。