为什么我的编码显示两次

本文关键字:两次 我的 编码 显示 为什么 | 更新日期: 2023-09-27 18:16:18

byte[] lengthBytes = new byte[4];
serverStream.Read(lengthBytes, 0, 4);
MessageBox.Show("'>>" + System.Text.Encoding.UTF8.GetString(lengthBytes) + "<<'");
MessageBox.Show("Hello");

这是我用来调试的代码。我现在有2个消息框。如果我使用Debug。WriteLine也被打印了两次

Msgbox 1: '>>/   (Note that this is still 4 characters long, the last 3 bytes are null.
Msgbox 2: '>>{"ac<<'
Msgbox 3: Hello

我试图发送4个字节的整数,消息的长度。这很好('/'是47的utf8)。问题是消息的前4个字节也被读取('{"ac')。我完全不知道这是怎么发生的,我已经调试了几个小时,我只是不能得到我的头。我的一个朋友建议我在StackOverflow上注册一个账户,所以我在这里:p

谢谢你的帮助:)

编辑:问

的人的真实代码

我的代码http://kutj.es/2ah-j9

为什么我的编码显示两次

你正在犯传统的程序员错误,每个人都必须犯一次错误来学习如何避免它并正确地做它。这主要是通过编写有bug的调试代码来偏离轨道,并使许多更难找到错误:

  • 永远不要编写使用MessageBox.Show()的调试代码。这是一个非常非常邪恶的函数,它会导致重入。这个昂贵的词意味着它只会冻结用户界面,不会冻结你的程序。它继续运行,其中一件可能出错的事情是您发布的代码再次被执行。重新输入。您将看到两个消息框。而且您的程序状态将完全损坏,因为编写代码时从未考虑过可以重新输入。这就是为什么你抱怨4字节的数据被吞掉了。

在这里使用的适当工具是确实冻结程序的特性。调试器断点。

  • 永远不要假设二进制数据可以转换为文本。您收到的这4个字节包含二进制零。这是没有性格的。更糟糕的是,它充当许多操作系统调用的字符串终止符,调试器使用的那种,Debug.WriteLine()等。这就是为什么你看不到<<"

此处使用的适当工具是调试器监视器或工具提示,它可以让您直接查看数组。如果你一定要生成一个诊断字符串,那么使用BitConverter.GetString()。

  • 永远不要假设流的Read()方法总是返回你所要求的字节数。在代码中使用返回值是一个硬性要求。这是你程序中真正的bug,也是你真正想要修复的。

正确的解决方案是继续调用Read(),直到您计算出您期望从先前读取的长度接收的字节数。你需要一个MemoryStream来存储你得到的字节块[]。

也许这个关于Encoding.GetString()的链接会对您有所帮助。注意的部分是:

如果要转换的数据仅在顺序块中可用(,例如从流中读取的数据)或者如果数据量非常大它需要被分成更小的块,你应该使用由派生类的GetDecoder方法返回的解码器对象。

问题是我启动了getMessage无效2次。这将启动while 2次(在不同线程中)。

Elgonzo帮我找到了问题,他是个很棒的人:)