Encoding.UTF8.GetString工作错误,从socket接收数据

时间:2011-10-22 12:02:02

标签: c# sockets

这些天我遇到了一个字节数组编码字符串的问题。 我使用套接字从服务器接收数据到缓冲区,然后我创建一个MemoryStream来从这个缓冲区读取数据到tempBuffer,其tempBuffer的固定长度为30到GetString

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

我使用textBox显示如下字符串:

tbSkill.Text = moTaSkill;

文本框中始终显示错误:

  1. 调试时我看到moTaSkill =“英雄的技能”
  2. 当在文本框上显示时,它只是“技能”或有时“技能”或“技能”
  3. 我尝试创建tempBuffer,其长度等于我将收到的字符串的长度。但没有成功。

    任何人都可以告诉我解决方法吗?

4 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

上传填充缓冲区的代码

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

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