C#BinaryReader.ReadChar在读取NetworkStream时抛出“ System.ArgumentException:输出char缓冲区太小”

use*_*454 5 c# networkstream binaryreader

NetworkStream从流类型的TCP套接字读取C#时,BinaryReader.ReadChar偶尔会引发异常System.ArgumentException: The output char buffer is too small to contain the decoded characters, encoding 'Unicode (UTF-8)'

所有缓冲区都有其默认大小(没有一个是手动设置的),并且设置更大的缓冲区大小不会影响该问题。

完全令人沮丧的是:

  • 使用断点并逐步通过ReadCharcall 行时,不会发生异常

  • 如果ReadChar先于该异常,则不会发生该异常Thread.Sleep(1000)(但仍会在较小的超时时发生)

  • 使用BinaryReaderon 时不会发生异常FileStream,在该位置存储了TCP服务器答案的所有精确字节。

那么,从套接字流中缓冲单个字符可能是与时间相关的问题?

mas*_*zov 6

我也有这个问题。以下是一些事实:

  1. System.ArgumentException: The output char buffer is too small to contain the decoded characters, encoding 'Unicode (UTF-8)'已知与UTF-8编码问题(无效的字符代码)有关,而不是与缓冲问题有关- 这里的详细信息

  2. NetworkStreamRead和其他方法)已知仅返回系统网络缓冲区中已经存在的字节数,而不是阻塞直到接收到所有请求的数据为止- 此处有详细信息。因此,需要Read循环使用以获取所有请求的数据

  3. BinaryReader已知当从中获取NetworkStream比预期少的数据时会引发异常,而不是使用循环来检索其余部分(是的,我敢肯定,这意味着一个错误!)- 这里有详细信息

因此,我的解决方案是部分重新实现BinaryReader(我称之为类BinReader),添加一些有用的功能并使用循环制作适当的Read方法:

public int Read( byte[] buf, int off, int count ) {
    int read = 0;
    while( read < count ) {
        int toread = count - read;
        int portion = BaseStream.Read( buf, off, toread );
        read += portion;
        off += portion;
    }
    return read;
}
Run Code Online (Sandbox Code Playgroud)

这为我解决了。