这些天我遇到了一个字节数组编码字符串的问题。
我使用套接字从服务器接收数据到缓冲区,然后我创建一个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;
文本框中始终显示错误:
我尝试创建tempBuffer,其长度等于我将收到的字符串的长度。但没有成功。
任何人都可以告诉我解决方法吗?
答案 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个字节,即使缓冲区较大。